簡體   English   中英

如何找到哪個MySQL查詢在NodeJS應用中導致錯誤?

[英]How can I find which MySQL query is causing errors in my NodeJS app?

我已經在NodeJS和HapiJS之上構建了一個api。

該應用程序在啟動時會加載大量數據,然后將其保存在內存中。 我的應用程序運行在具有16 GB RAM的服務器上,因此應該可以在內存中保留4 GB RAM。

但是,每次啟動應用程序時,此錯誤都會在日志中出現5次:

{ Error: connect ETIMEDOUT
    at Connection._handleConnectTimeout (/home/ec2-user/daemons/liar_lies/node_modules/mysql/lib/Connection.js:425:13)
    at Socket.g (events.js:291:16)
    at emitNone (events.js:86:13)
    at Socket.emit (events.js:185:7)
    at Socket._onTimeout (net.js:339:8)
    at ontimeout (timers.js:365:14)
    at tryOnTimeout (timers.js:237:5)
    at Timer.listOnTimeout (timers.js:207:5)
    --------------------
    at Protocol._enqueue (/home/ec2-user/daemons/liar_lies/node_modules/mysql/lib/protocol/Protocol.js:141:48)
    at Protocol.handshake (/home/ec2-user/daemons/liar_lies/node_modules/mysql/lib/protocol/Protocol.js:52:41)
    at Connection.connect (/home/ec2-user/daemons/liar_lies/node_modules/mysql/lib/Connection.js:136:18)
    at /home/ec2-user/daemons/liar_lies/node_modules/knex/lib/dialects/mysql/index.js:106:18
    at Promise._execute (/home/ec2-user/daemons/liar_lies/node_modules/bluebird/js/release/debuggability.js:300:9)
    at Promise._resolveFromExecutor (/home/ec2-user/daemons/liar_lies/node_modules/bluebird/js/release/promise.js:481:18)
    at new Promise (/home/ec2-user/daemons/liar_lies/node_modules/bluebird/js/release/promise.js:77:14)
    at Client_MySQL.acquireRawConnection (/home/ec2-user/daemons/liar_lies/node_modules/knex/lib/dialects/mysql/index.js:104:12)
    at Object.create (/home/ec2-user/daemons/liar_lies/node_modules/knex/lib/client.js:231:16)
    at Pool._createResource (/home/ec2-user/daemons/liar_lies/node_modules/generic-pool/lib/generic-pool.js:326:17)
    at Pool.dispense [as _dispense] (/home/ec2-user/daemons/liar_lies/node_modules/generic-pool/lib/generic-pool.js:314:12)
    at Pool.acquire (/home/ec2-user/daemons/liar_lies/node_modules/generic-pool/lib/generic-pool.js:392:8)
    at /home/ec2-user/daemons/liar_lies/node_modules/knex/lib/client.js:281:19
    at Promise._execute (/home/ec2-user/daemons/liar_lies/node_modules/bluebird/js/release/debuggability.js:300:9)
    at Promise._resolveFromExecutor (/home/ec2-user/daemons/liar_lies/node_modules/bluebird/js/release/promise.js:481:18)
    at new Promise (/home/ec2-user/daemons/liar_lies/node_modules/bluebird/js/release/promise.js:77:14)
  errorno: 'ETIMEDOUT',
  code: 'ETIMEDOUT',
  syscall: 'connect',
  fatal: true }

這是唯一的錯誤,每當應用啟動時就會發生5次。

但是,該應用程序似乎確實獲取了我希望它獲取的大多數數據,因此無論查詢拋出此錯誤,它都必須相當模糊。

我如何找出哪個查詢引發此錯誤?

stacktrace似乎沒有提到導致此問題的代碼行。 (我覺得這很令人沮喪。)

這些是我正在使用的模塊:

"boom": "3.1.2",
"code": "2.1.0",
"fs": "0.0.2",
"glob": "6.0.4",
"glue": "3.1.0",
"good-console": "5.3.0",
"good-file": "5.1.2",
"hapi": "16.0.2",
"html-entities": "1.2.0",
"joi": "7.2.2",
"knex": "0.12.6",
"knex-logger": "0.1.0",
"multiline": "1.0.2",
"mysql": "2.12.0",
"path": "0.12.7",
"plugo": "0.3.1"

我只知道有2個函數在啟動時會調用數據庫。 這是其中之一:

function build_maps_which_index_database_data(query, which_type_of_data_in_which_database_table) {

    DB.knex.raw(query).then(
        function(result) {
        var count_of_database_results = result[0].length;
        build_list_of_allowed_fields(result[0][0]);

        for(var how_many_records_processed_so_far = 0; how_many_records_processed_so_far < count_of_database_results; how_many_records_processed_so_far++) {
            var document = result[0][how_many_records_processed_so_far];
            var profile_id = document['profile_id'];
            document['which_type_of_data_in_which_database_table'] = which_type_of_data_in_which_database_table;
            document['item_id'] =  uuidV4(); 

            build_map_of_uuid_ids_to_documents(document);   

            Object.keys(document).forEach(function(name_of_field_in_database) {
                // avoiding name_of_field_in_database = profile_id
                if (name_of_field_in_database != 'profile_id') {
                    var string_from_database = document[name_of_field_in_database];
                    build_map_of_santized_words_to_uuid_ids(name_of_field_in_database, string_from_database, document['item_id']);
                }
            });
        }
        })
    .catch(function(e) {
            console.log('Error:     calling code was get_map_of_santized_words_to_uuid_ids'); 
            console.log('query was: ' + query); 
        console.error(e);      
    });
}

這些函數中的每一個都附加了一個“ catch”子句,因此我假設如果是導致錯誤的原因,那么我會在日志中看到。

有問題的錯誤不是由問題中包含的代碼引起的。

為了找出發送這些錯誤時發生了什么,請嘗試使用環境變量DEBUG=knex:*運行該應用程序。 這將向您顯示連接池中正在發生的情況以及向數據庫發送的查詢。

export DEBUG=knex:*
cd ~/yourapp
node server.js

要不就

cd ~/yourapp
DEBUG=knex:* node server.js

還要嘗試從應用程序中刪除代碼,直到應用程序中的代碼量最少為止,這仍然會產生這些錯誤。 之后,應該很容易找到問題的根本原因。

您可以做的另一件事是將調試信息添加到

knex.on('query-error', function (err, obj) { ... }); 

事件並檢查是否捕獲了這些錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM