मैं कई अलग-अलग ग्राहकों द्वारा उपयोग किए जाने वाले सॉफ़्टवेयर-ए-ए-सर्विस एप्लिकेशन का वरिष्ठ डेवलपर हूं। हमारा सॉफ्टवेयर Apache / PHP एप्लीकेशन सर्वर के एक क्लस्टर पर चलता है, जो एक MySQL बैकएंड द्वारा संचालित है। पर एक सॉफ्टवेयर के विशेष उदाहरण, श्रेणी नामों की सूची क्वेरी करने के लिए PHP कोड बाहर समय है जब ग्राहक की तुलना में अधिक 29 श्रेणियों है । मुझे पता है कि इससे कोई मतलब नहीं है; संख्या 30 के बारे में कुछ भी विशेष नहीं है जो इसे तोड़ देगा और अन्य ग्राहकों के पास 30 से अधिक श्रेणियां हैं, हालांकि, समस्या 100% प्रतिलिपि प्रस्तुत करने योग्य है जब इस एक स्थापना में 30 या अधिक श्रेणियां होती हैं और 30 से कम श्रेणियां होने पर चली जाती हैं।
प्रश्न में तालिका है:
CREATE TABLE IF NOT EXISTS `categories` (
`id` int(10) unsigned NOT NULL auto_increment,
`name` varchar(64) NOT NULL,
`title` varchar(128) NOT NULL,
`parent` int(10) unsigned NOT NULL,
`keywords` varchar(255) NOT NULL,
`description` text NOT NULL,
`status` enum('Active','Inactive','_Deleted','_New') NOT NULL default 'Active',
`style` enum('_Unknown') default NULL COMMENT 'Autoenum;',
`order` smallint(5) unsigned NOT NULL,
`created_at` datetime NOT NULL,
`modified_at` datetime default NULL,
PRIMARY KEY (`id`),
KEY `name` (`name`),
KEY `parent` (`parent`),
KEY `created_at` (`created_at`),
KEY `modified_at` (`modified_at`),
KEY `status` (`status`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='R2' AUTO_INCREMENT=33 ;
प्रश्न में कोड सभी श्रेणियों को लाने के लिए तालिका पर पुनरावृत्ति करता है। यह जारी करता है
SELECT * FROM `categories` WHERE `parent`=0 ORDER BY `order`,`name`
और फिर प्रत्येक पंक्ति के लिए इस क्वेरी को दोहराता है, लेकिन WHERE parent=$category_id
हर बार उपयोग करके । (मुझे यकीन है कि इस प्रक्रिया में सुधार किया जा सकता है, लेकिन यह शायद एक और सवाल है)
जहाँ तक मैं बता सकता हूँ, निम्नलिखित क्वेरी हमेशा के लिए लटकी हुई है:
SELECT * FROM `categories` WHERE `parent`=22 ORDER BY `order`,`name`
मैं सर्वर पर mysql क्लाइंट में इस क्वेरी को पूरी तरह से ठीक कर सकता हूं, और मैं इसे PHPMyAdmin में समस्याओं के बिना भी निष्पादित कर सकता हूं।
ध्यान दें कि यह वह विशिष्ट क्वेरी नहीं है जो समस्या है। अगर मैं DELETE FROM categories WHERE id=22
फिर ऊपर वाले के समान एक अलग क्वेरी लटकाऊंगा। इसके अलावा, जब मैं मैन्युअल रूप से इसे चलाता हूं , तो ऊपर की क्वेरी शून्य पंक्तियों को वापस कर देती है ।
मुझे संदेह था कि तालिका भ्रष्ट हो सकती है, और मैंने कोशिश की REPAIR TABLE
और OPTIMIZE TABLE
इन समस्याओं की सूचना दी और न ही इस मुद्दे को हल किया। मैंने टेबल को गिरा दिया और फिर से बनाया, लेकिन समस्या वापस आ गई। यह ठीक उसी तालिका संरचना और PHP कोड है जो अन्य ग्राहक किसी और के लिए कोई समस्या नहीं के साथ उपयोग कर रहे हैं, जिसमें ऐसे ग्राहक शामिल हैं जिनकी 30 से अधिक श्रेणियां हैं।
PHP कोड हमेशा के लिए नहीं आ रहा है। (यह नहीं है और अनंत लूप)
MySQL सर्वर i686 (MySQL समुदाय संस्करण (GPL) पर PC-linux-gnu के लिए mysqld Ver 5.0.92-समुदाय के साथ CentOS linux चला रहा है)
MySQL सर्वर पर लोड कम है: लोड औसत: 0.58, 0.75, 0.73, Cpu (s): 4.6% हमें, 2.9% sy, 0.0% ni, 92.2% id, 0.0% wa, 0.0% hi, 0.3% si, 0.0% सेंट। उपयोग किए जा रहे अयोग्य स्वैप (448k)
मैं इस समस्या का निवारण कैसे कर सकता हूं? क्या हो रहा है के रूप में किसी भी सुझाव?
अद्यतन: मैंने TRUNCE
तालिका को संपादित किया और डमी डेटा की 30 पंक्तियाँ डालीं:
INSERT INTO `categories` (`id`, `name`, `title`, `parent`, `keywords`, `description`, `status`, `style`, `order`, `created_at`, `modified_at`) VALUES
(1, 'New Category', '', 0, '', '', 'Inactive', NULL, 1, '2011-10-25 12:06:30', '2011-10-25 12:06:34'),
(2, 'New Category', '', 0, '', '', 'Inactive', NULL, 2, '2011-10-25 12:06:39', '2011-10-25 12:06:40'),
(3, 'New Category', '', 0, '', '', 'Inactive', NULL, 3, '2011-10-25 12:06:41', '2011-10-25 12:06:42'),
(4, 'New Category', '', 0, '', '', 'Inactive', NULL, 4, '2011-10-25 12:06:46', '2011-10-25 12:06:47'),
(5, 'New Category', '', 0, '', '', 'Inactive', NULL, 5, '2011-10-25 12:06:49', NULL),
(6, 'New Category', '', 0, '', '', 'Inactive', NULL, 6, '2011-10-25 12:06:51', '2011-10-25 12:06:52'),
(7, 'New Category', '', 0, '', '', 'Inactive', NULL, 7, '2011-10-25 12:06:53', '2011-10-25 12:06:54'),
(8, 'New Category', '', 0, '', '', 'Inactive', NULL, 8, '2011-10-25 12:06:56', '2011-10-25 12:06:57'),
(9, 'New Category', '', 0, '', '', 'Inactive', NULL, 9, '2011-10-25 12:06:59', '2011-10-25 12:06:59'),
(10, 'New Category', '', 0, '', '', 'Inactive', NULL, 10, '2011-10-25 12:07:01', '2011-10-25 12:07:01'),
(11, 'New Category', '', 0, '', '', 'Inactive', NULL, 11, '2011-10-25 12:07:03', '2011-10-25 12:07:03'),
(12, 'New Category', '', 0, '', '', 'Inactive', NULL, 12, '2011-10-25 12:07:05', '2011-10-25 12:07:05'),
(13, 'New Category', '', 0, '', '', 'Inactive', NULL, 13, '2011-10-25 12:07:06', '2011-10-25 12:07:07'),
(14, 'New Category', '', 0, '', '', 'Inactive', NULL, 14, '2011-10-25 12:07:08', '2011-10-25 12:07:09'),
(15, 'New Category', '', 0, '', '', 'Inactive', NULL, 15, '2011-10-25 12:07:11', '2011-10-25 12:07:12'),
(16, 'New Category', '', 0, '', '', 'Inactive', NULL, 16, '2011-10-25 12:07:13', '2011-10-25 12:07:14'),
(17, 'New Category', '', 0, '', '', 'Inactive', NULL, 17, '2011-10-25 12:09:41', '2011-10-25 12:09:42'),
(18, 'New Category', '', 0, '', '', 'Inactive', NULL, 18, '2011-10-25 12:09:47', NULL),
(19, 'New Category', '', 0, '', '', 'Inactive', NULL, 19, '2011-10-25 12:09:48', NULL),
(20, 'New Category', '', 0, '', '', 'Inactive', NULL, 20, '2011-10-25 12:09:48', NULL),
(21, 'New Category', '', 0, '', '', 'Inactive', NULL, 21, '2011-10-25 12:09:49', NULL),
(22, 'New Category', '', 0, '', '', 'Inactive', NULL, 22, '2011-10-25 12:09:50', NULL),
(23, 'New Category', '', 0, '', '', 'Inactive', NULL, 23, '2011-10-25 12:09:51', NULL),
(24, 'New Category', '', 0, '', '', 'Inactive', NULL, 24, '2011-10-25 12:09:51', NULL),
(25, 'New Category', '', 0, '', '', 'Inactive', NULL, 25, '2011-10-25 12:09:52', NULL),
(26, 'New Category', '', 0, '', '', 'Inactive', NULL, 26, '2011-10-25 12:09:53', NULL),
(27, 'New Category', '', 0, '', '', 'Inactive', NULL, 27, '2011-10-25 12:09:54', NULL),
(28, 'New Category', '', 0, '', '', 'Inactive', NULL, 28, '2011-10-25 12:09:55', NULL),
(29, 'New Category', '', 0, '', '', 'Inactive', NULL, 29, '2011-10-25 12:09:56', NULL),
(30, 'New Category', '', 0, '', '', 'Inactive', NULL, 30, '2011-10-25 12:09:57', NULL);
कोई भी माता-पिता , सभी श्रेणियां शीर्ष स्तर पर नहीं हैं। समस्या अभी भी है। PHP द्वारा निष्पादित निम्नलिखित क्वेरी विफल रहती है:
SELECT * FROM `categories` WHERE `parent`=22 ORDER BY `order`,`name`
यहाँ है EXPLAIN
:
mysql> EXPLAIN SELECT * FROM `categories` WHERE `parent`=22 ORDER BY `order`,`name`;
+----+-------------+------------+------+---------------+--------+---------+-------+------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+------+---------------+--------+---------+-------+------+-----------------------------+
| 1 | SIMPLE | categories | ref | parent | parent | 4 | const | 1 | Using where; Using filesort |
+----+-------------+------------+------+---------------+--------+---------+-------+------+-----------------------------+
1 row in set (0.00 sec)
अद्यतन # 2: मैंने अब निम्नलिखित में से सभी को आजमाया है:
- मैंने इस टेबल और डेटा को एक ही सॉफ्टवेयर के साथ एक अलग साइट पर कॉपी किया। समस्या तालिका का पालन नहीं करती थी । ऐसा लगता है कि यह एक डेटाबेस तक ही सीमित है।
- मैंने gbn के सुझाव के अनुसार सूचकांक को बदल दिया। समस्या बनी रही।
- मैंने तालिका को गिरा दिया और एक
InnoDB
तालिका के रूप में पुनः बनाया और उसी 30 परीक्षण पंक्तियों को ऊपर डाला। समस्या बनी रही।
मुझे संदेह है कि यह इस डेटाबेस के साथ कुछ होना चाहिए ...
अद्यतन # 3: मैंने पूरी तरह से डेटाबेस को गिरा दिया और इसे एक नए नाम के तहत फिर से बनाया, जिससे उसका डेटा आयात किया गया। समस्या बनी हुई है।
मैंने पाया है कि वास्तविक PHP स्टेटमेंट जो लटका हुआ है वह एक कॉल है mysql_query()
। इसके बाद के कथन कभी निष्पादित नहीं होते हैं।
जबकि वह कॉल हैंग होता है, MySQL थ्रेड को सोने के रूप में सूचीबद्ध करता है !
mysql> show full processlist;
+-------+------------------+-----------------------------+----------------------+---------+------+-------+-----------------------+
| Id | User | Host | db | Command | Time | State | Info |
+-------+------------------+-----------------------------+----------------------+---------+------+-------+-----------------------+
| 5560 | root | localhost | problem_db | Query | 0 | NULL | show full processlist |
----- many rows which have no relevancy; only rows from this customer's app are shown ------
| 16341 | shared_db | oak01.sitepalette.com:53237 | shared_db | Sleep | 308 | | NULL |
| 16342 | problem_db | oak01.sitepalette.com:60716 | problem_db | Sleep | 307 | | NULL |
| 16344 | shared_db | oak01.sitepalette.com:53241 | shared_db | Sleep | 308 | | NULL |
| 16346 | problem_db | oak01.sitepalette.com:60720 | problem_db | Sleep | 308 | | NULL |
+-------+------------------+-----------------------------+----------------------+---------+------+-------+-----------------------+
अद्यतन # 4: मैंने इसे दो तालिकाओं के संयोजन तक सीमित कर दिया है , categories
ऊपर media_images
दी गई तालिका और 556 पंक्तियों वाली तालिका। यदि media_images
तालिका में 556 पंक्तियाँ कम हैं, या categories
तालिका में 30 पंक्तियाँ कम हैं, तो समस्या दूर हो जाती है। ऐसा लगता है कि यह MySQL सीमा के कुछ प्रकार मैं यहाँ मार रहा है ...
# 5 अद्यतन: मैंने बस डेटाबेस को पूरी तरह से एक अलग MySQL सर्वर पर ले जाने की कोशिश की और समस्या दूर हो गई ... तो यह मेरे उत्पादन डेटाबेस सर्वर से संबंधित है ...
अद्यतन # 6: यहां प्रासंगिक PHP कोड है जो हर बार हैं:
public function find($type,$conditions='',$order='',$limit='')
{
if($this->_link == self::AUTO_LINK)
$this->_link = DFStdLib::database_connect();
if(is_resource($this->_link))
{
$q = "SELECT ".($type==_COUNT?'COUNT(*)':'*')." FROM `{$this->_table}`";
if($conditions)
{
$q .= " WHERE $conditions";
}
if($order)
{
$q .= " ORDER BY $order";
}
if($limit)
{
$q .= " LIMIT $limit";
}
switch($type)
{
case _ALL:
DFSkel::log(DFSkel::LOG_DEBUG,"mysql_query($q,$this->_link);");
$res = @mysql_query($q,$this->_link);
DFSkel::log(DFSkel::LOG_DEBUG,"res = $res");
यह कोड उत्पादन में है और अन्य सभी संस्थापनों पर ठीक काम करता है। बस एक स्थापित पर, यह लटका हुआ है $res = @mysql_query($q,$this->_link);
। मुझे पता है क्योंकि मैं mysql_query
डिबग लॉग में देखता हूं , और नहीं res =
, और जब मैं strace
PHP प्रक्रिया करता हूं , तो इसे लटका दिया जाता हैread(
अद्यतन # जो कुछ भी है, मैं-मैं-नफरत- यह- (# ^ -issue! ) अब यह मेरे दो ग्राहकों के लिए होने लगा है। मैंने अभी-अभी निकाल दिया है tcpdump
और ऐसा लग रहा है कि MySQL से प्रतिक्रिया कभी भी पूरी तरह से नहीं भेजी जाती है। पूर्ण MySQL प्रतिक्रिया भेजे जाने से पहले टीसीपी स्ट्रीम बस लटका हुआ लगता है। (मैं अभी भी जांच कर रहा हूं)
अद्यतन # मैं-गया-पूरी तरह से पागल-लेकिन-यह-कार्य-अब-थोड़े: ठीक है, इसका कोई मतलब नहीं है, लेकिन मुझे एक समाधान मिल गया है। यदि मैं MySQL सर्वर के eth2
इंटरफ़ेस में एक दूसरा IP पता असाइन करता हूं , और NFS ट्रैफ़िक के लिए एक IP और MySQL के लिए दूसरा IP उपयोग करता हूं , तो समस्या दूर हो जाती है। ऐसा लगता है जैसे मैं किसी तरह ... आईपी पते को ओवरलोडिंग कर रहा हूं अगर दोनों एनएफएस + MySQL ट्रैफ़िक दोनों उस आईपी पर जाते हैं। लेकिन यह शून्य समझ में आता है क्योंकि आप एक आईपी पते को "अधिभार" नहीं दे सकते हैं। एक इंटरफ़ेस सुनिश्चित करना, लेकिन यह एक ही इंटरफ़ेस है।
किसी भी विचार यहाँ बिल्ली में क्या चल रहा है? यह संभवतः इस बिंदु पर एक यूनिक्स.एसई या सर्वरफॉल्ट प्रश्न है ... (कम से कम यह अब काम करता है ...)
अद्यतन # क्यों-ओह-क्यों: यह समस्या अभी भी हो रही है। यह दो अलग-अलग आईपी का उपयोग करके भी होने लगा है। मैं नए निजी आईपी बना सकता हूं, लेकिन स्पष्ट रूप से कुछ गलत है।