Warning: A long semaphore wait

前端 未结 2 1042
说谎
说谎 2020-12-30 03:29

For the past 4 days I have had massive problems with my nightly updates, except for 1 night were it all went fine in between these 4 days.

During th

相关标签:
2条回答
  • 2020-12-30 04:12

    The problem was with innodb_adaptive_hash_index

    innodb_adaptive_hash_index=0 and a restart solved the problem.

    As ive stated in the question

    "The architectural changes in MySQL 5.6 and higher make more workloads suitable for disabling the adaptive hash index than in earlier releases, although it is still enabled by default."

    This worked for me as I have not had the same issue again.

    0 讨论(0)
  • 2020-12-30 04:14

    Had such a problem too. The database broke without reason several times a day. I'm not sure if this helped me, but my solution is to optimize all tables. Three days so far, this problem no longer appears.

    There are many methods for optimizing all tables, but I'll give you an example of how to do this using PHP via the linux console

            #!/bin/php -n
            <?php
        // /bin/php -n /sysmyx/mysql/hand_optimize_all_tables.php
        dl('mysqlnd.so');
        dl('mysqli.so');
    $timestart  = time();
    $n=0;
    $con=mysqli_connect("localhost","roootmysql","passss");
    
    if (mysqli_connect_errno())  {  echo "mysql error".PHP_EOL;
    exit;
    }
    mysqli_query($con,"SET GLOBAL innodb_buffer_pool_dump_now = 1");
    $res = mysqli_query($con,"SHOW DATABASES");
    while ($row = mysqli_fetch_assoc($res)) {
    $db_name=$row['Database'];
    if ($db_name!="mysql" && $db_name!="information_schema" && $db_name!="performance_schema" && $db_name!="" && $db_name!="sys") {
    echo '*'.$db_name.'*'.PHP_EOL;
    //!!!!!!!!!!!!!!!!!!!!!!!// $query="SHOW TABLE STATUS FROM $db_name where Data_free>0;";
    $query="SHOW TABLE STATUS FROM $db_name";
    $tabbll=mysqli_query($con,$query);
    while ($row2 = mysqli_fetch_assoc($tabbll)) {
    $n++;
    $opt_table='`'.$db_name.'`.`'.$row2['Name'].'`';
    $query2="OPTIMIZE TABLE $opt_table";
    $time1 = time();
    mysqli_query($con,$query2);
    $time2 = time();
    $time3 = $time2-$time1;
    echo $n.' '.$time3.' '.$row2['Data_free'].' '.$opt_table.PHP_EOL;
    }}}
    mysqli_query($con,"SET GLOBAL innodb_buffer_pool_load_now = 1");
    mysqli_close($con);
    $timeend  = time();
    $time  = $timeend-$timestart;
    ?>
    

    Also part of the settings my.cnf

    innodb_thread_concurrency=0
    flush_time=0
    innodb_adaptive_hash_index=0
    innodb_adaptive_hash_index_parts=1
    innodb_purge_threads=1
    innodb_fatal_semaphore_wait_threshold=60
    

    UPDATE 17-07-2019

    I found the problem that caused me this error.

    The problem was that I had a table of 4,000 rows. This table received about 1000 updates every second. Also, from this table at the same time, there are about 500 selections every second. Usually, the time of selection is 0.006 seconds, but after several days the selection time becomes 5 seconds. After that, the moment that thousands of selects were gathered in the queue and there was a moment of error "A long semaphore wait".

    Possible solutions:

    1) Make another table structure, check the indixes, split the table into several tables.

    2 )Do every few hours optimize the table.

    3) Сome up with a caching system for this table

    Possible search problems:

    A useful script that will help you see what queries are gathered at the time of mysql crash. Run the script every minute through the cron.

    #!/bin/bash 
    USER=$(</sys_snting/mysql_user)
    PASSWORD=$(</sys_snting/mysql_pass)
    num=$(mysql --user=$USER --password=$PASSWORD -s -N -e "SELECT count(*) FROM information_schema.processlist ;")
    if [ $num -ge 500 ] ; then
    mysql --user=$USER --password=$PASSWORD -e "show full processlist" > /media/bug/$(date +%Y%m%d%H%M%S)_$num.txt
    echo $num
    
    # Kill selections that can lead to "A long semaphore wait"
    # mysql --user=$USER --password=$PASSWORD -N -e "SELECT Id FROM information_schema.processlist where INFO like '%SELECT \`d_narfe\` FROM \`maitableep_com\`.\`5000_active\` WHERE%';" | while IFS= read -r loop
    # do
    #     echo "$loop"
    # mysqladmin --user=$USER --password=$PASSWORD  kill $loop
    # done 
    fi
    
    0 讨论(0)
提交回复
热议问题