MySQL server has gone away, 不一致的错误,单一脚本引起

MySQL server has gone away, inconsistent error, caused by a single script

我有一个 PHP 脚本正在启动一个 SQL 查询,这需要几秒钟的时间 returns 大约 15K+ 个结果,在根据找到的数据进行复杂计算之后我服务器上的数据库 table,名为 table.

得到结果后,应该将这些记录插入(使用替换)到我服务器上的另一个数据库 table。

table 是一个简单的核心 table 时,该脚本曾经完美运行。我后来修改了 SQL 查询以使用来自 VIEW table 的数据,我们可以将其称为 view_table,它基于 table 但有一个额外的列是根据 table 计算的苍蝇。

这使得脚本开始崩溃我的整个 SQL 服务器,每隔一段时间,抛出这个错误:

PHP Warning: mysqli::query(): MySQL server has gone away in /home/user/script.php on line 109

下面是第 109 行:

function getRecordsFromDB(){
    logMemoryUtilizationDetails();
    file_put_contents(LOG_DIRECTORY.'service.log', date("d/m:H:i").':'."getRecordsFromDB::Entry".PHP_EOL, FILE_APPEND);
    global $sourceConn;
    $selectQuery = file_get_contents(__DIR__.'/my-query.sql');
    $items = array();
    $result = $sourceConn->query($selectQuery); // LINE 109
    if ($result){
        if ($result->num_rows > 0) {

            while($row = $result->fetch_assoc()) {
                $item = new Item();
                $item->id               = $row['id'];
                $item->itemId               = $row['itemid'];

我尝试记录创建以查看脚本在启动和退出时使用了多少内存,当它成功时,它在峰值时仅使用了大约 37MB 的 RAM。

我的服务器在 4 个内核上有 6GB RAM。

我的服务器上没有其他脚本 运行 导致 SQL 服务器像这样崩溃,所以我确定是这个脚本导致了崩溃。

这是我服务器的MY.CNF:

[mysqld]
# disable mysql strict mode
sql_mode=""

log-error=/var/lib/mysql/host.myhost.com.err
performance_schema=1

query_cache_type=0
query_cache_size=0
query_cache_limit=0

key_buffer_size=16M
max_connections=200
max_tmp_tables=1
table_open_cache=2000
local-infile=0
thread_cache_size=4
innodb_file_per_table=1
default-storage-engine=MyISAM
innodb_use_native_aio=0
max_allowed_packet=1024M
innodb_buffer_pool_size=800M
open_files_limit=10000
#wait_timeout=500
tmp_table_size=256M
max_heap_table_size=256M
innodb_buffer_pool_instances=1
#general_log=on
#general_log_file = /var/lib/mysql/all-queries.log

slow-query-log=0
slow-query-log-file=/var/lib/mysql/slow_queries.log
long_query_time=1.0
#log_queries_not_using_indexes=1

这是来自我的 PHP.INI(针对我正在使用的 PHP 7.2):

max_execution_time = 240

max_input_time = 60

max_input_vars = 1000

memory_limit = 512M


[MySQLi]

mysqli.max_persistent = -1

;mysqli.allow_local_infile = On

mysqli.allow_persistent = On

mysqli.max_links = -1

mysqli.cache_size = 2000

mysqli.default_port = 3306

mysqli.default_socket =

mysqli.default_host =

mysqli.default_user =

mysqli.default_pw =

mysqli.reconnect = Off

我在这些文件中没有看到任何 mysql.connect_timeout 设置。

我还有许多其他脚本,它们都工作正常,所以我不想全局更改某些内容,因为我担心它会导致我的服务器出现其他问题。

看起来像是超时或失败的查询。请粘贴您正在使用的 sql 查询。您也可以尝试通过将查询粘贴到您的 mysql IDE(我最喜欢 Navicat)并在其前面添加 'explain extended'(无引号)来查看查询可能导致此问题的位置。所以你的查询看起来像 'explain extended select ...(all 300 lines)' 寻找大于 4 的键,没有主键和查询的行,对于初学者来说非常高。 此外,看起来您可能想要考虑创建一个存储过程而不是视图,您可以在其中 select 将所有内容放入临时 table 中,然后在下一个过程中执行即时计算值询问。当然,您需要配置 my.cnf 以识别临时 table,以便在会话完成后将其销毁。此外,如果您有任何复制或服务器集群,请确保在创建临时 table 之前停止 binlog,然后在查询完成且会话即将关闭后启动它。

如果愿意,请粘贴您的 my.cnf(mysql 配置文件)以确保您的配置最适合大型查询。

此外,为了排除故障,您可能需要暂时增加 php.ini 中的最长执行时间。