Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

MySQL त्रुटि 1436:थ्रेड स्टैक ओवररन, साधारण क्वेरी के साथ

1436 - थ्रेड स्टैक ओवररन:131072 बाइट स्टैक में उपयोग किए गए 6136 बाइट्स, और 128000 बाइट्स की आवश्यकता है।

1436 त्रुटि mysql 5.1 कोड में ER_STACK_OVERRUN_NEED_MORE से मेल खाती है:

[email protected]:include> pwd
/home/malff/BZR_TREE/mysql-5.1/include
[email protected]:include> grep 1436 mysqld_error.h
#define ER_STACK_OVERRUN_NEED_MORE 1436

देखा गया त्रुटि प्रिंट करने वाला कोड sql/sql_parse.cc, function check_stack_overrun() :

में है।
bool check_stack_overrun(THD *thd, long margin,
                         uchar *buf __attribute__((unused)))
{
  long stack_used;
  DBUG_ASSERT(thd == current_thd);
  if ((stack_used=used_stack(thd->thread_stack,(char*) &stack_used)) >=
      (long) (my_thread_stack_size - margin))
  {
    char ebuff[MYSQL_ERRMSG_SIZE];
    my_snprintf(ebuff, sizeof(ebuff), ER(ER_STACK_OVERRUN_NEED_MORE),
                stack_used, my_thread_stack_size, margin);
    my_message(ER_STACK_OVERRUN_NEED_MORE, ebuff, MYF(ME_FATALERROR));

देखे गए मानों से, मार्जिन 128000 है, और my_thread_stack_size 131072 है।

check_stack_overrun() को एकमात्र कॉल जो 128000 बाइट आरक्षित करने का प्रयास करती है वह है:

bool
sp_head::execute(THD *thd)
{
  /* Use some extra margin for possible SP recursion and functions */
  if (check_stack_overrun(thd, 8 * STACK_MIN_SIZE, (uchar*)&old_packet))
    DBUG_RETURN(TRUE);

STACK_MIN_SIZE का मान 16000 है:

[email protected]:sql> pwd
/home/malff/BZR_TREE/mysql-5.1/sql
[email protected]:sql> grep STACK_MIN_SIZE *.h
mysql_priv.h:#define STACK_MIN_SIZE          16000   // Abort if less stack during eval.

अब तक, सब कुछ सर्वर के लिए अपेक्षित रूप से काम करता है:

  • कोड एक ट्रिगर निष्पादित करता है, जिसे sp_head::execute के साथ कार्यान्वित किया जाता है।
  • MySQL रनटाइम जाँचता है कि स्टैक पर कम से कम 128000 बाइट्स हैं
  • यह जांच विफल हो जाती है (ठीक है), और ट्रिगर निष्पादन एक त्रुटि के साथ समाप्त होता है।

MySQL ट्रिगर निष्पादन के लिए आवश्यक स्टैक की मात्रा स्वयं ट्रिगर जटिलता या शामिल तालिकाओं की सामग्री / संरचना पर निर्भर नहीं करती है।

क्या असली सवाल है, मुझे लगता है, क्यों थ्रेड_स्टैक केवल 128K (131072) पर है।

'thread_stack' नाम का सर्वर वैरिएबल C में sql/mysqld.cc में 'my_thread_stack_size' के रूप में लागू किया गया है:

  {"thread_stack", OPT_THREAD_STACK,
   "The stack size for each thread.", &my_thread_stack_size,
   &my_thread_stack_size, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK,
   1024L*128L, ULONG_MAX, 0, 1024, 0},

1024L*128L इस पैरामीटर के लिए न्यूनतम मान है। डिफ़ॉल्ट मान DEFAULT_THREAD_STACK है, जिसे शामिल/my_pthread.h:

में परिभाषित किया गया है।
#ifndef DEFAULT_THREAD_STACK
#if SIZEOF_CHARP > 4
/*
  MySQL can survive with 32K, but some glibc libraries require > 128K stack
  To resolve hostnames. Also recursive stored procedures needs stack.
*/
#define DEFAULT_THREAD_STACK    (256*1024L)
#else
#define DEFAULT_THREAD_STACK    (192*1024)
#endif
#endif

इसलिए, डिफ़ॉल्ट रूप से, स्टैक का आकार 192K (32 बिट) या 256K (64 बिट आर्किटेक्चर) होना चाहिए।

सबसे पहले, जांचें कि mysqld बाइनरी कैसे संकलित की गई थी, यह देखने के लिए कि डिफ़ॉल्ट मान क्या है:

[email protected]:sql> pwd
/home/malff/BZR_TREE/mysql-5.1/sql
[email protected]:sql> ./mysqld --no-defaults --verbose --help | grep thread_stack
...
  --thread_stack=#    The stack size for each thread.
thread_stack                      262144

मेरे सिस्टम पर, मुझे 64 बिट प्लेटफॉर्म पर 256K मिला है।

यदि अलग-अलग मान हैं, तो हो सकता है कि कोई अलग-अलग संकलन विकल्पों के साथ सर्वर का निर्माण करे, जैसे -DDEFAULT_THREAD_STACK (या सिर्फ स्रोत संशोधित) ... मैं सवाल करूंगा कि उस मामले में बाइनरी कहां से आ रही है।

दूसरा, कॉन्फ़िगरेशन फ़ाइल में दिए गए डिफ़ॉल्ट मानों के लिए my.cnf की जाँच करें। स्पष्ट रूप से (और कम मान के साथ) थ्रेड_स्टैक के लिए एक मान सेट करने वाली एक पंक्ति निश्चित रूप से दिखाई देने वाली त्रुटि का कारण बनेगी।

अंत में, इस तरह की त्रुटि के लिए सर्वर लॉग फ़ाइल की जाँच करें (sql/mysqld.cc देखें) :

sql_print_warning("Asked for %lu thread stack, but got %ld",
                  my_thread_stack_size, (long) stack_size);

सर्वर कोड कॉल करता है:

  • pthread_attr_setstacksize() स्टैक का आकार सेट करने के लिए
  • pthread_attr_getstacksize() यह सत्यापित करने के लिए कि किसी थ्रेड में वास्तव में कितना स्टैक है और यदि pthread लाइब्रेरी का कम उपयोग किया जाता है तो लॉग में शिकायत करता है।

लंबी कहानी छोटी, त्रुटि दिखाई देती है क्योंकि सर्वर के साथ भेजे गए डिफ़ॉल्ट मानों की तुलना में थ्रेड_स्टैक बहुत छोटा है। ऐसा हो सकता है:

  • विभिन्न संकलन विकल्पों के साथ सर्वर का कस्टम निर्माण करते समय
  • my.cnf फ़ाइल में डिफ़ॉल्ट मान बदलते समय
  • यदि पर्थ्रेड लाइब्रेरी में ही कुछ गलत हो गया है (सिद्धांत रूप में कोड को पढ़ने से, मैंने इसे स्वयं कभी नहीं देखा है)।

मुझे आशा है कि यह प्रश्न का उत्तर देगा।

सादर,-- मार्क अल्फ़

अपडेट (2014-03-11), "कैसे ठीक करें" को और अधिक स्पष्ट बनाने के लिए।

क्या हो रहा है, सभी संभावना में, यह है कि थ्रेड_स्टैक फ़ाइल के लिए डिफ़ॉल्ट मान my.cnf फ़ाइल में बदल दिया गया था।

इसे कैसे ठीक करें, यह मामूली है, my.cnf फ़ाइल में थ्रेड_स्टैक कहां सेट है, और या तो सेटिंग को हटा दें (एक सभ्य डिफ़ॉल्ट मान प्रदान करने के लिए सर्वर कोड पर भरोसा करना, इसलिए अगली बार ऐसा नहीं होता है) या स्टैक बढ़ाएं आकार।

अपडेट (2021-04-28), जांचें कि थ्रेड_स्टैक कहां से आता है:

तालिका का उपयोग करें performance_schema.variables_info यह पता लगाने के लिए कि दिया गया चर कहाँ से आता है।

mysql> select * from variables_info where VARIABLE_NAME = 'thread_stack';
+---------------+-----------------+---------------+-----------+----------------------+----------+----------+----------+
| VARIABLE_NAME | VARIABLE_SOURCE | VARIABLE_PATH | MIN_VALUE | MAX_VALUE            | SET_TIME | SET_USER | SET_HOST |
+---------------+-----------------+---------------+-----------+----------------------+----------+----------+----------+
| thread_stack  | COMPILED        |               | 131072    | 18446744073709550592 | NULL     | NULL     | NULL     |
+---------------+-----------------+---------------+-----------+----------------------+----------+----------+----------+
1 row in set (0.01 sec)

यहाँ डिफ़ॉल्ट फ़ैक्टरी मान है (mysqld बाइनरी में संकलित)।

एक और उदाहरण:

mysql> select * from variables_info where VARIABLE_NAME = 'thread_stack';
+---------------+-----------------+----------------------------------------------------------------+-----------+----------------------+----------+----------+----------+
| VARIABLE_NAME | VARIABLE_SOURCE | VARIABLE_PATH                                                  | MIN_VALUE | MAX_VALUE            | SET_TIME | SET_USER | SET_HOST |
+---------------+-----------------+----------------------------------------------------------------+-----------+----------------------+----------+----------+----------+
| thread_stack  | EXPLICIT        | /home/malff/CODE/GIT/GIT_TRUNK/build-dbg/mysql-test/var/my.cnf | 131072    | 18446744073709550592 | NULL     | NULL     | NULL     |
+---------------+-----------------+----------------------------------------------------------------+-----------+----------------------+----------+----------+----------+
1 row in set (0.00 sec)

यहाँ थ्रेड_स्टैक रिपोर्ट की गई my.cnf फ़ाइल में सेट है।

रेफमैन:

https://dev.mysql .com/doc/refman/8.0/hi/performance-schema-variables-info-table.html



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. JDBC और MySQL के साथ संचार लिंक विफलता का समाधान

  2. स्मृति-कुशल अंतर्निहित SqlAlchemy इटरेटर/जनरेटर?

  3. Android JDBC काम नहीं कर रहा:ClassNotFoundException ड्राइवर पर

  4. GROUP_BYs के दो बाएं जॉइन में से GROUP_CONCAT से अजीब डुप्लिकेट व्यवहार

  5. MONTH () उदाहरण – MySQL