"त्रुटि:अद्वितीय अनुक्रमणिका नहीं बना सका
विवरण:तालिका में डुप्लीकेट मान हैं।"
यह त्रुटि Postgres द्वारा फेंक दी जाती है जब यह प्राथमिक कुंजी तालिका में डुप्लिकेट पंक्तियों का सामना करती है, इनमें से किसी भी कमांड REINDEX या CREATE UNIQUE INDEX को विफल करके।
तालिका में डुप्लिकेट पंक्तियाँ क्यों मौजूद हैं?
निश्चित रूप से निश्चित नहीं और न ही कोई सिद्ध व्याख्या…
मेरे दिमाग में दो बातें हैं।
सबसे पहले, यह सूचकांक निर्माण में देरी हो सकती है या यदि आपने डेटाबेस में अनुक्रम साझा किए हैं, तो दो अलग-अलग प्राथमिक कुंजी तालिकाओं पर साझा करना डेटा को तालिका (pg_restore) में पुनर्स्थापित करते समय कारण हो सकता है। दूसरे, यदि उस टेबल पर कोई बड़ा लेन-देन हो रहा है और बैकएंड पर किसी ने इंस्टेंस को अचानक रोक दिया है, जो इंडेक्स (प्राथमिक कुंजी) को सही पंक्ति में इंगित करने में विफल हो सकता है।
इसे कैसे ठीक करें ?
ठीक है, सामान्य अभ्यास के रूप में, जब हम किसी तालिका में डुप्लिकेट पंक्तियों का सामना करते हैं (किसी भी कारण के बावजूद), हम पहले डुप्लिकेट पंक्तियों को फ़िल्टर करते हैं और उन्हें हटा देते हैं, और बाद में REINDEX करके समस्या को ठीक करना चाहिए।
डुप्लिकेट पंक्तियों को खोजने के लिए क्वेरी:
select count(*),primary_column from table_name group by primary_column having count(*) > 1;
डुप्लिकेट पंक्तियों को हटाने के बाद भी REINDEX या CREATE UNIQUE INDEX विफल हो जाता है, इसका मतलब है कि आपकी अनुक्रमणिका ठीक से साफ़ नहीं हुई है। उपरोक्त क्वेरी 100% परिणाम उन्मुख आउटपुट नहीं दे रही है जो आप उम्मीद कर रहे हैं, क्योंकि क्वेरी उस इंडेक्स को चुनने जा रही है जो पहले से ही डुप्लिकेट पंक्तियों से दूषित है। नीचे दी गई व्याख्या योजना देखें।
postgres=# explain select count(*),id from duplicate_test group by id having count(*) > 1;
QUERY PLAN
-------------------------------------------------------------------------------------------------------
GroupAggregate (cost=0.00..5042.90 rows=99904 width=4)
Filter: (count(*) > 1)
-> Index Scan using duplicate_test_pkey on duplicate_test (cost=0.00..3044.82 rows=99904 width=4)
(3 rows)
हमें मुख्य तालिका से डुप्लिकेट पंक्तियों के CTID को पकड़ने और सशर्त विवरण के साथ CTID + PRIMARY KEY VALUE के रूप में हटाने की आवश्यकता है।
मैंने इसी तरह की त्रुटि के साथ परिदृश्य को पुन:पेश करने के लिए प्राथमिक कुंजी तालिका को वॉयलेट करने के लिए pg_catalogs के साथ थोड़ा सा खेला है। (कृपया इसे न करें)
postgres=# create unique index idup on duplicate_test(id);
ERROR: could not create unique index "idup"
DETAIL: Key (id)=(10) is duplicated.
मेरी तालिका परिभाषा और डेटा:
postgres=# d duplicate_test
Table "public.duplicate_test"
Column | Type | Modifiers
--------+---------+-----------
id | integer | not null
name | text |
Indexes:
"duplicate_test_pkey" PRIMARY KEY, btree (id)
postgres=# select * from duplicate_test ;
id | name
----+---------
10 | Raghav ---Duplicate
20 | John H
30 | Micheal
10 | Raghav ---Duplicate
(4 rows)
अब, इसे ठीक करते हैं….
चरण 1. केवल दो कॉलम मान CTID और PRIMARY KEY को खींचकर प्रभावित तालिका से एक नई तालिका बनाएं।
postgres=# CREATE TABLE dupfinder AS SELECT ctid AS tid, id FROM duplicate_test;
SELECT 4
चरण 2. अब, सटीक डुप्लिकेट प्राप्त करने के लिए डुप्लिकेट फ़ाइंडर क्वेरी को CTID के साथ चलाने दें।
postgres=# select * from dupfinder x where exists (select 1 from dupfinder y where x.id = y.id and x.tid != y.tid);
tid | id
-------+----
(0,1) | 10
(0,5) | 10
(2 rows)
चरण 3. उपरोक्त परिणाम पर, अब आप CTID के साथ मुख्य तालिका (प्रभावित तालिका) से एक पंक्ति को हटा सकते हैं।
postgres=# delete from duplicate_test where ctid='(0,5)' and id=10;
DELETE 1
चरण 4. अब, आपका REINDEX या CREATE UNIQUE INDEX सफल होगा।
postgres=# create unique index idup on duplicate_test(id);
CREATE INDEX
postgres=# select * from duplicate_test ;
id | name
----+---------
10 | Raghav
20 | John H
30 | Micheal
(3 rows)
चरण 5. सिस्टम कैटलॉग के साथ-साथ सीटीआईडी मूवमेंट को अपडेट करने के लिए टेबल पर तत्काल वैक्यूम विश्लेषण करना न भूलें।
कृपया अपनी टिप्पणियाँ साझा करें।