精华内容
下载资源
问答
  • 为了优化OceanBase的query timeout设置方式,特调研MySQL关于timeout的处理,记录如下。 代码如下: mysql> show variables like ‘%time%’; +—————————-+——————-+ | Variable_name | Value | +——...
  • sql 查询超时已过期 SQL Server provides you with a good solution to automate a lot of your administrative tasks using the SQL Server Agent jobs. These jobs are handled from the operating system side ...

    sql 查询超时已过期

    SQL Server provides you with a good solution to automate a lot of your administrative tasks using the SQL Server Agent jobs. These jobs are handled from the operating system side by a Windows service that is responsible for executing these jobs and feeding the SQL Server systems tables with the metadata about these jobs. The system database that is used by the SQL Server Agent for the job management called the msdb database. All information related to the job steps, schedules and the history can be found in the msdb database tables. The msdb system database is also responsible for the SQL Server Mail, Service Broker, SQL Server Maintenance Plans and the databases backup history.

    SQL Server为您提供了一个很好的解决方案,可以使用SQL Server代理作业自动执行许多管理任务。 这些作业由Windows服务从操作系统端处理,该Windows服务负责执行这些作业并向SQL Server系统表提供有关这些作业的元数据。 SQL Server代理用于作业管理的系统数据库称为msdb数据库。 与作业步骤,时间表和历史记录有关的所有信息都可以在msdb数据库表中找到。 msdb系统数据库还负责SQL Server邮件,Service Broker,SQL Server维护计划和数据库备份历史记录。

    The msdb database tables that store information about the SQL Server Agent jobs are: the dbo.sysjobactivity which contains information about the SQL Server Agent job activates, the dbo.sysjobhistory table that keeps information about the execution history for the agent jobs , the dbo.sysjobs table that contains information about all the SQL Agent jobs, the dbo.sysjobschedules table that stores information about the schedules for all SQL Agent job, the dbo.sysjobservers table that contains the association of the SQL Agent jobs with the target servers, the dbo.sysjobsteps table that stores information about the SQL Agent jobs steps and the dbo.sysjobstepslogs table that stores logs about the SQL Agent jobs steps.

    存储有关SQL Server代理作业信息的msdb数据库表包括:dbo.sysjobactivity,其中包含有关SQL Server Agent作业已激活的信息; dbo.sysjobhistory表,其中包含有关代理作业的执行历史的信息; dbo。 sysjobs表(包含有关所有SQL Agent作业的信息), dbo.sysjobschedules表(存储有关所有SQL Agent作业的日程表的信息), dbo.sysjobservers表(包含SQL Agent作业与目标服务器的关联), dbo .sysjobsteps表用于存储有关SQL Agent作业步骤的信息,而dbo.sysjobstepslogs表用于存储有关SQL Agent作业步骤的日志。

    There are three main database fixed roles in the msdb database that control the access to the SQL Server Agent. The first role is SQLAgentUserRole that is least privileged one in the msdb database. This role members have access on the local jobs and local job schedules that they owned only. This role members can see only the Jobs node from the SQL Server Agent.

    msdb数据库中有三个主要的数据库固定角色,用于控制对SQL Server代理的访问。 第一个角色是SQLAgentUserRole ,它在msdb数据库中拥有最少的特权。 该角色成员有权访问他们仅拥有的本地作业和本地作业计划。 该角色成员只能从SQL Server代理看到Jobs节点。

    The second role is SQLAgentReaderRole, that members have access to see all the jobs and job schedules they owned and the ones they don’t own. But they can’t change on the jobs and schedules that they don’t own. This role members can see only the Jobs node from the SQL Server Agent.

    第二个角色是SQLAgentReaderRole ,成员有权查看他们拥有的所有作业和作业计划以及不拥有的作业。 但是他们无法更改自己不拥有的工作和时间表。 该角色成员只能从SQL Server代理看到Jobs节点。

    The last role is SQLAgentOperatorRole, which is the most privileged role in the msdb database. The members of this role can start and stop the execution of the local jobs, enable and disable it, and they have the ability to delete the jobs history for these local jobs. But they are not able to change in the jobs that they don’t own. This role members can see all the SQL Server Agent nodex except the Error Logs one.

    最后一个角色是SQLAgentOperatorRole ,它是msdb数据库中最特权的角色。 该角色的成员可以启动和停止本地作业的执行,启用和禁用本地作业,并且可以删除这些本地作业的作业历史记录。 但是他们无法改变他们不拥有的工作。 该角色成员可以看到除错误日志之一以外的所有SQL Server代理节点。

    我们如何才能在步骤级别上获得正确的工作结果? ( How could we get the correct job result on the step level? )

    One of the DBA’s daily tasks is checking the SQL Server Agent jobs that are scheduled at night and report back any failure to the corresponding system owners. A system owner reported to me that her scheduled job failed last night even though the evidence indicates that it was completed successfully. To get to the bottom of this I went through the job steps, and I found out that the job contains remote query that is using linked server and it gave Query Timeout Expired error.

    DBA的日常任务之一是检查晚上安排SQL Server代理作业,并将任何故障报告给相应的系统所有者。 一位系统所有者向我报告说,她的预定工作昨晚失败了,即使有证据表明该工作已成功完成。 要深入了解这一点,我完成了工作步骤,发现该工作包含使用链接服务器的远程查询,并且出现了“查询超时过期”错误。

    Doing the below steps, I was under the impression that the system owner’s job was completed successfully, even though at later stage I found out the opposite.

    执行以下步骤,给我的印象是,系统所有者的工作已成功完成,尽管在稍后阶段我发现相反的情况。

    The result of the SQL server agent jobs can be checked by drilling down the job to View History as below:

    可以通过按以下方式将作业向下钻取至“查看历史记录”来检查SQL Server代理作业的结果:

    The job history window will be displayed showing valuable information about the last few runs of the chosen scheduled job including Date, Server, Job Name, Result Message and the Duration in seconds:

    将显示作业历史记录窗口,其中显示了有关所选计划作业的最后几次运行的重要信息,包括日期,服务器,作业名称,结果消息和以秒为单位的持续时间:

    As shown in the snapshot above, the last run of our job succeeded. But the system’s owner complained that the job failed?

    如上面的快照所示,上一次工作成功完成。 但是系统的所有者抱怨工作失败了吗?

    Let’s expand the job log to show the result of each step as below:

    让我们展开作业日志以显示每个步骤的结果,如下所示:

    The step’s result still misleading us by showing the green tick sign beside the step, showing that the step also completed successfully. Going through the step result message carefully, we are shocked with this message: “Query timeout expired". [SQLSTATE 01000] (Message 7412).  The step succeeded.”. This means that the query duration exceeded the server’s remote query timeout duration, raising this message from the SQL linked server OLE DB provider.

    通过在步骤旁边显示绿色的勾号,该步骤的结果仍然会误导我们,表明该步骤也已成功完成。 仔细查看步骤结果消息,我们对以下消息感到震惊:“ 查询超时到期”。[SQLSTATE 01000](消息7412)步骤成功。 ”。这意味着查询持续时间超过了服务器的远程查询超时持续时间,从SQL链接服务器OLE DB提供程序引发此消息。

    SQL Server remote query is a query that contains outgoing connection to a remote database. A SQL server parameter called remote query timeout is used to decide how long a remote query will take before initiating timeout message. The default remote query timeout value is 600 seconds. Setting the value to 0 will disable the timeout, so the query will wait until it is canceled.

    SQL Server远程查询是一个包含到远程数据库的传出连接的查询。 一个称为远程查询超时的 SQL Server参数用于确定启动超时消息之前远程查询将花费多长时间。 远程查询的默认超时值为600秒。 将该值设置为0将禁用超时,因此查询将等待直到被取消。

    If there is a network latency between you server and the remote SQL server, you can change this value to resolve the query timeout issue from the Connections tab of the Server Properties dialog box below:

    如果服务器和远程SQL Server之间存在网络延迟,则可以从下面的“服务器属性”对话框的“连接”选项卡中更改此值以解决查询超时问题:

    Our main concern here, how we could have an automated way to trace the query timeout message within the SQL Agent job steps result in our case, or any failure message in your case, in order to get a better indication of the job status.

    这里我们主要关心的问题是,如何在我们的情况下自动跟踪SQL Agent作业步骤中的查询超时消息,或者在您的情况下跟踪失败消息,以便更好地指示作业状态。

    Let’s try first to view the job steps result that contains query timeout message, which is stored in the sysjobhistory and sysjobs tables from the msdb system database:

    让我们首先尝试查看包含查询超时消息的作业步骤结果,该消息存储在msdb系统数据库的sysjobhistory和sysjobs表中:

     
    USE msdb
    Go 
    SELECT JS.name AS JobName,
    JH.step_name AS StepName,
    JH.message AS StepMessage, 
    JH.run_duration AS StepDuration, 
    JH.run_date AS TS
    FROM sysjobhistory JH 
    INNER JOIN sysjobs JS  ON JS.job_id = JH.job_id
    WHERE JH.message LIKE '%Query timeout expired%'
    ORDER BY  JH.run_date desc
    GO
     
    

    Executing the query, the result will be as follows:

    执行查询,结果如下:

    To be initiative and to avoid future complains related to the same problem, it is better to automate this process and review it as a part of your daily check. To achieve that, we will create a table that will host the query results, modify the previous script to fill that table with the previous day’s jobs result.

    为了主动起见并避免以后再提出与同一问题有关的投诉,最好使此过程自动化并将其作为日常检查的一部分进行检查。 为此,我们将创建一个表来托管查询结果,修改前一个脚本以将前一天的工作结果填充到该表中。

    Let’s start with the table creation using the simple T-SQL script below:

    让我们开始使用下面的简单T-SQL脚本创建表:

     
    USE [SQLShackDemo]
    GO
     
    SET ANSI_NULLS ON
    GO
     
    SET QUOTED_IDENTIFIER ON
    GO
     
    CREATE TABLE [dbo].[JobStepsHistory](
    	[JobName] [nvarchar](50) NULL,
    	[StepName] [nvarchar](50) NULL,
    	[StepMessage] [nvarchar](max) NULL,
    	[StepDuration] [int] NULL,
    	[TS] [datetime] NULL
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
     
    GO
     
    

    Once the table is ready, we will modify our script to insert into that table, any query timeout message during the last day. It is better to schedule the below script as a SQL Agent job that will be run the first thing in the morning, to make sure that all the scheduled jobs are finished:

    表准备好后,我们将修改脚本以将最后一天中的任何查询超时消息插入该表。 最好将下面的脚本作为SQL Agent作业进行调度,该脚本将在第一天早上运行,以确保所有调度的作业均已完成:

     
    USE [SQLShackDemo]
    GO
    INSERT INTO DBO.JobStepsHistory
    SELECT JS.name, 
    JH.step_name,
    JH.message, 
    JH.run_duration, 
    JH.run_date
    FROM MSDB.DBO.sysjobhistory JH 
    INNER JOIN MSDB.DBO.sysjobs JS ON JS.job_id = JH.job_id
    WHERE JH.message LIKE '%Query timeout expired%'
    AND datepart (day,CONVERT(CHAR(10), CAST(STR(JH.run_date,8, 0) AS dateTIME), 111))  = datepart(day,getdate()-1)
     ORDER BY  JH.run_date desc
    GO
     
    

    What is required from your side now, is a simple select statement from that table, every morning, to make sure that no query timeout occurred last night on your scheduled jobs. Also you can have more advanced automated way to send you the content of that table by email. You can also modify the previous script to trace any type of misleading messages you may face by replacing the query timeout message in LIKE statement inside WHERE clause.

    您现在需要的是每天早晨从该表中进行选择的简单语句,以确保昨晚对计划的作业没有查询超时发生。 您还可以采用更高级的自动方式,通过电子邮件向您发送该表的内容。 您还可以通过替换WHERE子句中LIKE语句中的查询超时消息来修改以前的脚本以跟踪您可能会遇到的任何类型的误导性消息。

    You can simulate a test scenario for the “Query Timeout Expired” problem by creating a SQL stored procedure in the remote database, including WAITFOR delay exceeding the default 10 minutes.

    您可以通过在远程数据库中创建SQL存储过程(包括超过默认10分钟的WAITFOR延迟)来模拟针对“查询超时已过期”问题的测试方案。

    翻译自: https://www.sqlshack.com/monitor-the-query-timeout-expired-message-from-a-sql-server-agent-job/

    sql 查询超时已过期

    展开全文
  • 全局配置或针对某个sql语句特殊针对性配置: https://www.cnblogs.com/qin-derella/p/6128598.html

    全局配置或针对某个sql语句特殊针对性配置:

    https://www.cnblogs.com/qin-derella/p/6128598.html

    展开全文
  • 关于mysql设置查询超时时间

    千次阅读 2021-04-15 11:51:24
    查询超时时间设置,是在mysql-connector-java底层是通过定时器Timer来实现statement timeout的功能,也就是说,对于设置了statement timeout的sql,将会导致mysql创建定时Timer来执行sql 因此对于这查询超时设置...

    建议

    查询超时时间设置,是在mysql-connector-java底层是通过定时器Timer来实现statement timeout的功能,也就是说,对于设置了statement timeout的sql,将会导致mysql创建定时Timer来执行sql

    因此对于这查询超时设置,只能够在正常的业务代码中进行配置(但是这个就要做到读写分离,要是写SQL配置了超时,那么server就会出现脏数据需要做幂等设计了,同时高QPS场景、分库分表、读写分离场景下不建议使用)原理部分下面讲解

     

    举例说明:

    • mysql:mysql-connector-java:8.0.19
    • com.xueqiu.infra.toolbox:xueqiu-toolbox-datasource:0.0.50

    1.直接使用PreparedStatement

    ConnectionPool pool = ConnectionPool.newRWPool("redis_manager", infos).orElseThrow(() -> new IllegalStateException("init failed."));

     

    String query = "select sleep(5)";

    try (Connection connection = pool.getConnection(); PreparedStatement pstmt = connection.prepareStatement(query)) {

       pstmt.setQueryTimeout(1);

       System.out.println(pstmt.execute());

    }

    异常信息

    Exception in thread "main" com.mysql.cj.jdbc.exceptions.MySQLTimeoutException: Statement cancelled due to timeout or client request
    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:113)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953)
    at com.mysql.cj.jdbc.ClientPreparedStatement.execute(ClientPreparedStatement.java:370)
    at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_execute(FilterChainImpl.java:3409)
    at com.alibaba.druid.filter.FilterEventAdapter.preparedStatement_execute(FilterEventAdapter.java:440)
    at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_execute(FilterChainImpl.java:3407)
    at com.alibaba.druid.proxy.jdbc.PreparedStatementProxyImpl.execute(PreparedStatementProxyImpl.java:167)
    at com.alibaba.druid.pool.DruidPooledPreparedStatement.execute(DruidPooledPreparedStatement.java:498)
    at com.xueqiu.infra.toolbox.datasource.ConnectionPoolRWImplFunctionTest.main(ConnectionPoolRWImplFunctionTest.java:31)

    2.使用JDBCTemplate 

    ConnectionPool pool = ConnectionPool.newRWPool("redis_manager", infos).orElseThrow(() -> new IllegalStateException("init failed."));

    //这个SpringJDBCTemplate是业务中看到大多数项目都是这么自己封装后使用的

    SimpleSpringJDBCTemplate springJDBCTemplate = new SimpleSpringJDBCTemplate(pool);

    JdbcTemplate jdbcTemplate = springJDBCTemplate.getJdbcTemplate();

    jdbcTemplate.setQueryTimeout(1);

    String query = "select sleep(5)";

    jdbcTemplate.execute(query);

    异常信息

    Exception in thread "main" org.springframework.dao.QueryTimeoutException: StatementCallback; SQL [select sleep(5)]; Statement cancelled due to timeout or client request; nested exception is com.mysql.jdbc.exceptions.MySQLTimeoutException: Statement cancelled due to timeout or client request
    at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:120)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
    at org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1397)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:387)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:414)
    at com.xueqiu.snowflake.usercenter.extend.service.impl.JDBCTemplateTest.main(JDBCTemplateTest.java:26)
    Caused by: com.mysql.jdbc.exceptions.MySQLTimeoutException: Statement cancelled due to timeout or client request
    at com.mysql.jdbc.StatementImpl.executeInternal(StatementImpl.java:862)
    at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:745)
    at com.alibaba.druid.filter.FilterChainImpl.statement_execute(FilterChainImpl.java:2958)
    at com.alibaba.druid.filter.FilterAdapter.statement_execute(FilterAdapter.java:2473)
    at com.alibaba.druid.filter.FilterEventAdapter.statement_execute(FilterEventAdapter.java:188)
    at com.alibaba.druid.filter.FilterChainImpl.statement_execute(FilterChainImpl.java:2956)
    at com.alibaba.druid.proxy.jdbc.StatementProxyImpl.execute(StatementProxyImpl.java:147)
    at com.alibaba.druid.pool.DruidPooledStatement.execute(DruidPooledStatement.java:619)
    at org.springframework.jdbc.core.JdbcTemplate$1ExecuteStatementCallback.doInStatement(JdbcTemplate.java:405)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:375)
    ... 2 more

     

    原理部分

    尽管statement timeout很灵活,但是在高并发的情况下,会创建大量的线程,一些场景下并不建议使用。
    原因在于,mysql-connector-java底层是通过定时器Timer来实现statement timeout的功能,也就是说,对于设置了statement timeout的sql,将会导致mysql创建定时Timer来执行sql,意味着高并发的情况下,mysql驱动可能会创建大量线程。
    以下是模拟设置statement timeout之后,通过jstack命令查看的结果。

    "MySQL Statement Cancellation Timer" #19 daemon prio=5 os_prio=31 tid=0x00007ffdef092000 nid=0xa703 in Object.wait() [0x00007000029c7000]
    java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x000000076ae72f08> (a java.util.TaskQueue)
    at java.lang.Object.wait(Object.java:502)
    at java.util.TimerThread.mainLoop(Timer.java:526)
    - locked <0x000000076ae72f08> (a java.util.TaskQueue)
    at java.util.TimerThread.run(Timer.java:505)

    可以看到这里包含了一个名为Mysql Statement Cancellation Timer的线程,这就是用于控制sql执行超时的定时器线程。
    在高并发的情况下,大量的sql同时执行,如果设置了statement timeout,就会出现需要这样的线程。
    在mysql-connector-java驱动的源码中,体现了这个逻辑。
    在查询StatementImpl中定义了一个超时Timer

    com.mysql.cj.jdbc.ClientPreparedStatement#executeInternal

    protected <M extends Message> ResultSetInternalMethods executeInternal(int maxRowsToRetrieve, M sendPacket, boolean createStreamingResultSet,

            boolean queryIsSelectOnly, ColumnDefinition metadata, boolean isBatch) throws SQLException {

        synchronized (checkClosed().getConnectionMutex()) {

            try {

     

                JdbcConnection locallyScopedConnection = this.connection;

     

                ((PreparedQuery<?>) this.query).getQueryBindings()

                        .setNumberOfExecutions(((PreparedQuery<?>) this.query).getQueryBindings().getNumberOfExecutions() + 1);

     

                ResultSetInternalMethods rs;

     

                CancelQueryTask timeoutTask = null;

     

                try {

                    timeoutTask = startQueryTimer(this, getTimeoutInMillis());

     

                    if (!isBatch) {

                        statementBegins();

                    }

     

                    rs = ((NativeSession) locallyScopedConnection.getSession()).execSQL(thisnull, maxRowsToRetrieve, (NativePacketPayload) sendPacket,

                            createStreamingResultSet, getResultSetFactory(), metadata, isBatch);

     

                    if (timeoutTask != null) {

                        stopQueryTimer(timeoutTask, truetrue);

                        timeoutTask = null;

                    }

     

                finally {

                    if (!isBatch) {

                        this.query.getStatementExecuting().set(false);

                    }

     

                    stopQueryTimer(timeoutTask, falsefalse);

                }

     

                return rs;

            catch (NullPointerException npe) {

                checkClosed(); // we can't synchronize ourselves against async connection-close due to deadlock issues, so this is the next best thing for

                              // this particular corner case.

     

                throw npe;

            }

        }

    }

    com.mysql.cj.AbstractQuery#startQueryTimer

    public CancelQueryTask startQueryTimer(Query stmtToCancel, int timeout) {

        if (this.session.getPropertySet().getBooleanProperty(PropertyKey.enableQueryTimeouts).getValue() && timeout != 0) {

            CancelQueryTaskImpl timeoutTask = new CancelQueryTaskImpl(stmtToCancel);

            this.session.getCancelTimer().schedule(timeoutTask, timeout);

            return timeoutTask;

        }

        return null;

    }

     

     

    public void stopQueryTimer(CancelQueryTask timeoutTask, boolean rethrowCancelReason, boolean checkCancelTimeout) {

        if (timeoutTask != null) {

            timeoutTask.cancel();

     

            if (rethrowCancelReason && timeoutTask.getCaughtWhileCancelling() != null) {

                Throwable t = timeoutTask.getCaughtWhileCancelling();

                throw ExceptionFactory.createException(t.getMessage(), t);

            }

     

            this.session.getCancelTimer().purge();

     

            if (checkCancelTimeout) {

                checkCancelTimeout();

            }

        }

    }

    com.mysql.cj.NativeSession#getCancelTimer

    public synchronized Timer getCancelTimer() {

        if (this.cancelTimer == null) {

            this.cancelTimer = new Timer("MySQL Statement Cancellation Timer", Boolean.TRUE);

        }

        return this.cancelTimer;

    }

    这里我们看到ClientPreparedStatement内部,提供了一个名为MySQL Statement Cancellation Timer的定时器。
    在sql执行时,如果设置了statement timeout,则将sql包装成一个task,通过Timer进行执行:mysql 驱动源码里有多处使用到了这个Timer,这里以ClientPreparedStatement的executeQuery方法为例进行讲解,包含了以下代码片段:
    可以看到,在指定statement timeout的情况下,mysql内部会将sql执行操作包装成一个CancelTask,然后通过定时器Timer来运行。

    Timer实际上是与StatementImpl绑定的,同一个StatementImpl执行的多个sql,会共用这个Timer。
    默认情况下,这个Timer是不会创建的,一旦某个StatementImpl上执行的一个sql,指定了statement timeout,此时这个Timer才创建,一直到这个StatementImpl被销毁时,Timer才会取消。


    在一些场景下,如分库分表、读写分离,如果使用的数据库中间件是基于smart-client方式实现的,会与很多库建立连接,由于其底层最终也是通过mysql-connector-java创建连接,这种场景下,如果指定了statement timeout,那么应用中将会存在大量的Timer线程,在这种场景下,并不建议设置。

    扩展部分

    spring事务的超时机制,实际上是还是通过Statement.setQueryTimeout进行设置,每次都是把当前事务的剩余时间,设置到下一个要执行的sql中。
    事实上,spring的事务超时机制,需要ORM框架进行支持,例如mybatis-spring提供了一个SpringManagedTransaction,里面有一个getTimeout方法,就是通过从spring中获取事务的剩余时间。

    @Transactional(timeout = 3)
    如果同时配置了,@Transactional注解上的配置,将会覆盖默认的配置。

    transaction timeout的实现原理可以用以下流程进行描述,假设事务超时为5秒,需要执行3个sql:

     start transaction  #事务超时为5秒
       |
      \|/
      sql1  #statement timeout设置为5秒
       |
       |    #执行耗时1s,那么整个事务超时还剩4秒 
      \|/
      sql2  #设置statement timeout设置为4秒
       |
       |    #执行耗时2秒,整个事务超时还是2秒
      \|/ 
      sql3  #设置statement timeout设置为2秒
       |
      ---   #假设执行耗时超过2s,那么整个事务超时,抛出异常   

    通常是因为连接池大小设置的不合理。如何设置合理的线程池大小需要进行综合考虑。

    这里以sql执行耗时、要支撑的qps为例:
    假设某个接口的sql执行耗时为5ms,要支撑的最大qps为1000。一个sql执行5ms,理想情况下,一个Connection一秒可以执行200个sql。
    又因为支持的qps为1000,那么理论上我们只需要5个连接即可。
    当然,实际情况远远比这复杂,例如,我们没有考虑连接池内部的逻辑处理耗时,mysql负载较高执行sql变慢,应用发生了gc等,这些情况都会导致获取连接时间变长。
    建议是,比理论值,高3-5倍。

    1 应用启动时,出现获取连接超时异常
            可以通过调大initPoolSize。如果连接池有延迟初始化(lazy init)功能,也要设置为立即初始化,否则,只有第一次请求访问数据库时,才会初始化连接池。这个时候容易出现获取链接超时。
    2 业务高峰期,出现获取连接超时异常
            如果是偶然出现,可以忽略。如果出现的较为频繁,可以考虑调大maxPoolSize和minPoolSize。

     

     

    参考链接:

    https://stackoverflow.com/questions/20889062/jdbctemplate-setquerytimeout-specific-for-each-query-i-e-query-level

    https://blog.csdn.net/liaonanfeng88/article/details/98029330

    https://www.mysql.com/cn/products/connector/

    展开全文
  • Mybatis查询超时

    千次阅读 2019-04-13 20:16:18
    文章目录问题现象问题排查初次排查探因解决方案通过elasticSearch查询其他方案补充说明 问题现象 测试同学反馈,商品查询功能,输入字母或汉字正常,输入数字搜索时报错。 问题排查 初次排查 查看了一下耗时点,在...

    问题现象

    测试同学反馈,商品查询功能,输入字母或汉字正常,输入数字搜索时报错。

    问题排查

    初次排查

    查看了一下耗时点,在mybatis执行到DruidDataSource.getConnect方法之间耗时很久(两次,每次都差不多100s左右)。
    在这里插入图片描述

    猜测:连接池问题,全部被占用,在等待连接?
    查看了下getConnection代码, 里面才开始获取连接,说明这个中间过程还没有进行连接获取

    public DruidPooledConnection getConnection() throws SQLException {
        return getConnection(maxWait);
    }
    

    这个功能,在其他环境验证的时候正常,上线很久了,也没有暴露过问题。查看了这个接口对应的请求,在那个点附近的几十、百多秒,之前、之后的都在1s内。
    在这里插入图片描述

    当时查看部署服务器,那个时间段CPU耗时较高。环境之前出现过不稳定的情况,当时以为环境问题,适当加大了接口超时时间。
    在这里插入图片描述

    问题再现

    第二天,测试反馈又重现了。一次可以是凑巧,两次可能性很低。
    看了下请求数据,超时请求,输入的搜索关键字是"2"。关键字会去模糊匹配商品名称和条码。匹配到很多商品?
    查看了下数据库里面的商品,搜索条件下模糊匹配到几W条。pinpoint里面参数也印证了。
    在这里插入图片描述

    对比分析了下之前输入中文或字母搜索的,匹配的商品数量很少。
    由于是测试环境,之前批量造数据的时候,商品名称不规范,数字"2"匹配到了很多。

    至此找到了根本原因,如下:
    我们的商品条码和商品名称是存放在两张表的。查看代码实现,是先去条码表模糊匹配,找到一批商品ukid,然后在作为入参,去商品表里面做分页查询,计算总量等。
    商品数据量很大,mybatis做动态sql拼接时耗时很久。 从mybatis开始执行,到getConnection,中间是完成SQL组装。

    商品表查询,xml配置

    <select id="selectRsDefineds" parameterType="java.lang.Long" resultMap="BaseResultMap">
      select
      <include refid="Base_Column_List" />
      from rs_defined r
      where
      defined_ukid IS NOT NULL
      <if test="buIds != null">
        and definer_id in
        <foreach close=")" collection="buIds" item="ownerUkid" open="(" separator=",">
          #{ownerUkid}
        </foreach>
      </if>
      <if test="definedName != null">
        and
        (
        defined_name LIKE #{definedName}
        <if test="inDefinedUkidList != null">
          or defined_ukid in
          <foreach close=")" collection="inDefinedUkidList" item="definedUkid" open="(" separator=",">
            #{definedUkid}
          </foreach>
        </if>
        )
      </if>
      <if test="statusList != null">
        and status in
        <foreach close=")" collection="statusList" item="status" open="(" separator=",">
          #{status}
        </foreach>
      </if>
      <if test="statusList == null">
        and status = 1
      </if>
      <if test="typeList != null">
        and defined_type in
        <foreach close=")" collection="typeList" item="type" open="(" separator=",">
          #{type}
        </foreach>
      </if>
      <if test="debarUkids != null">
        and defined_ukid NOT IN
        <foreach close=")" collection="debarUkids" item="debarDefinedUkid" open="(" separator=",">
          #{debarDefinedUkid}
        </foreach>
      </if>
      <if test="sku != null">
        and sku = #{sku,jdbcType=BIGINT}
      </if>
      <if test="sort != null">
        ORDER BY ${sort}
      </if>
      <if test="limit != null">
        <if test="offset != null">
          limit ${offset}, ${limit}
        </if>
        <if test="offset == null">
          limit ${limit}
        </if>
      </if>
    </select>
    
    

    解决方案

    通过elasticSearch查询

    直接把所有商品数据同步到es,通过es做搜索。
    自测耗时500ms左右。 (总量:28w+,匹配到的数据量:15w+,虚拟机)

    公司已有es环境,es本身用于搜索,对大数据量筛选过滤、匹配度等支持更好。而且调整成本不高。

    其他方案

    • 自身在程序中做SQL拼接,不要用mybatis的。 针对这种特定场景,没必要所有的均如此
    • 表结构设计调整,条码、名称 聚合到一张表中进行搜索匹配

    补充说明

    mybatis做动态sql拼接,很久以前碰到过一次栈溢出的。当时查询到SQL拼接使用的visitor模式,构造了比较复杂的语法树。
    本次这块没有去往下分析。有大神欢迎赐教,或者有资料分享下,谢

    之前栈溢出的记录
    https://blog.csdn.net/LG772EF/article/details/58636910

    展开全文
  • phoenix查询超时

    2020-07-13 17:22:19
    由于数据量增大,phoenix查询超时 Error: Operation timed out. (state=TIM01,code=6000) java.sql.SQLTimeoutException: Operation timed out. 调整下HBase RPC Timeout 和 Phoenix Query Timeout时间
  • 最近生产运维反馈,手机银行查询个人交易流水信息,首次查询时,总报错 “查询超时”。经手机银行分析后,是由于 ods返回数据超时。运维中心,要求ods排查处理该问题。 当邮件发送到我这时,头大的很,因为这个问题...
  • C#操作MySQL查询超时01 前言02 正文03 后记 01 前言 在做一个Winform程序,配合MySQL处理数据,为此在MySQL中设计了几个视图。由于没做太多优化,执行SQL时间大于30秒就报错。还由于使用了第三方的ORM框架,找不到...
  • 目前两个客户端扩展库连接超时可以设置选项来操作,比如mysqli: $mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 5); 关于 Mysqli 提供的 options 选项可以参考 https://www.php.net/manual/zh/mysq
  • JDBC语句设置查询超时

    千次阅读 2019-10-25 17:19:35
    statement.setQueryTimeout(timeout);
  • 线上用的sqlserver2005数据库,里面有一个表有400多万条数据,然后程序调用数据时显示超时(只有这一个表超时),aspx.cs中写的sql语句,sql语句是根据姓名随机查询前三十五条,问问大家改怎么解决,求大神帮忙。...
  • 我创建了一个用户定义的过程,该过程结合了几个最短路径查询,但是如果它们花费的时间太长,我想退出所有这些最短路径搜索。 我的代码没有超时如下所示: StandardExpander orderedExpander = new O...
  • 当用户输入时间区间过大可能会导致跨平台查询底层数据量过大,查询速度慢、超时、撑爆内存,进而造成服务卡死或宕机。2. 由于数据量的多少和时间区间的长短并无之间联系(数据量多少与业务有关,有时候一秒内几千笔...
  • pymysql设置查询超时时间

    千次阅读 2020-09-27 17:13:06
    参数中有连接超时的配置型, 但是没有查询超时的配置信息, 到pymysql官网上查了下, 发现读数据超时, 写数据超时 的配置项都有, 意识到是我的版本太out了, 然后更新了pymysql的依赖版本为0.9.3, 在初始化连接时, ...
  • 大家先看一下优化前的数据库查询时间及页面响应时间: 大家可以看到 数据库查询时间达到了12秒 而由于页面还要多查询一次总行数,响应时间达到了惊人的33秒!这已经无法正常使用了,看上面的查询语句我们能发现...
  • 在是用DBeaver连接Clickhouse做查询时,有时候会出现连接或查询超时的情况,这个时候可以在连接的参数中添加设置socket_timeout参数来解决问题。 具体添加过程如下: 1、打开连接设置面板 2、进入编辑驱动设置 ...
  • kibana查询超时

    千次阅读 2019-09-20 10:58:16
    kibana做了代理,可能是nginx的代理那边设置的连接时间较短,查询时间较长,出现连接超时,这种情况,设置nginx的配置即可 #nginx没有设置代理,以下参数是以秒为单位 fastcgi_connect_timeout 300; fastcgi_send...
  • PHP连接MySQL主要是使用Mysql提供的 libmysqlclient 的客户端库,同时也延伸出来 mysql 和 mysqli 两套PHP的扩展,相对来说 mysqli 比 mysql 更好,更稳定。
  • 最近搞superset 发现查询的时候超过1分钟就timeout,nginx 504,还以为是config.py里面的配置的问题 SUPERSET_WEBSERVER_TIMEOUT = 60 * 2 改过之后没用,最后发现用ip 加 port没问题,用域名访问就有问题,所以...
  • hibernate 设置查询超时时间

    千次阅读 2019-07-18 11:20:07
    pstmt.setQueryTimeout(5);
  • 目前用的solr都没有设置超时,所以压力比较大的时候查询会越来越慢,也就越积越多,最终可能让 solr 挂了。总是想要个 timeout 功能,可能会对解决此问题有一定帮助。之前看lucene 2.4新特性时,没太注意。昨日注意...
  • 使用no_cursor_timeout collection = self.db[tb_name] cols = collection.find(no_cursor_timeout=True) for col in cols: # do something cols.cl...
  • 上面运行起来就超时,条件改成其他CompanyID都正常。 后来把select count(1)改成select count(*)就都可以了 好像之前有一次也是这样,我把*改成1,现在又改回来了哈 这个是怎么回事,数据库的问题吗...
  • 网狐数据库提示查询超时已过期

    千次阅读 2018-12-11 13:55:15
    也是这个问题的错误,即日志log文件自增长过长,log 自增长配置 10%扩容 2014GMax,但是如果log过大50G,10%增长就是5G,这样数据库分配时间超长,在此时间期内请求数据,数据是无响应的,即超时过期。 USE[master] ...
  • 数据库环境: WINDOWS2008R2 SQLSERVER2008R2 ...某系统应用查询超时 相关SQL: SELECT v.OBarcode Barcode, v.CBarcode, v.ZID, v.FromName ZNAME, v.ItemName, v.Batch, v.OrderNo, ...
  • MongoDB 查询超时异常的原因及解决办法 在对超过百万条记录的集合进行聚合操作时,偶尔会发生Read timed out 异常,本文分析了ConnectionTimeOut和SocketTimeOut的区别,并提出该问题的解决办法。 作者:忙碌的...
  • dapper--查询超时时间

    千次阅读 2019-05-29 09:30:00
    在实际项目于中,会执行运算量很大的执行过程,时间很长。...于是就使用的dapper的查询超时时间 当前使用Dapper调用存储过程中的SQL语句进行数据备份的任务,但出现 CommandTimeout 执行超时的...
  • mysql5.7.22 sql查询超时设置

    千次阅读 2018-08-10 14:36:31
    SELECT /*+ MAX_EXECUTION_TIME(1000) */ status, count(*) FROM articles GROUP BY status... //sql中设置注释表示超时 SET SESSION MAX_EXECUTION_TIME=2000; //设置会话过期 SET GLOBAL MAX_EXECUTION_TIME=2000...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 249,660
精华内容 99,864
关键字:

查询超时