MySQL: Duplicate entry for key

Apollon Oikonomopoulos apoikos at csl.mech.ntua.gr
Tue Sep 4 11:31:45 EEST 2007


Καλημέρα,

On Saturday 01 September 2007 20:08:00 Panagiotis Palias wrote:
> Αλέξανδρος Διαμαντίδης wrote:
>
> root at sardela:/etc# mysql -u root -p -h localhost sv1bkng_sv1grc <
> /tmp/phpbb_db_backup.sql
> Enter password:
> ERROR 1062 (23000) at line 179520: Duplicate entry 'åîåôüóåùí' for key 1
>
> Η γραμμή που χτυπάει το λάθος είναι η 2η από τις 3 που παραθέτω, πολύ
> πιο πάνω από αυτές υπάρχουν πολλές άλλες τέτοιες γραμμές, που όμως δε
> βγάζουν λάθος.
>
> INSERT INTO phpbb_search_wordlist (word_text, word_id, word_common)
> VALUES('ÌÑÏÕÌÉÄÇÓ', '180693', '0');
> INSERT INTO phpbb_search_wordlist (word_text, word_id, word_common)
> VALUES('åîåôüóåùí', '1843', '0');
> INSERT INTO phpbb_search_wordlist (word_text, word_id, word_common)
> VALUES('åììáíïõçë', '3453', '0');
>
> Δηλαδή στο link που μου έδωσες δεν κατάλαβα αν φταίει όντως κάτι, μιας
> και το συντακτικό είναι σωστό.

Τυχαίνει να έχω αντιμετωπίσει το ίδιο πρόβλημα κατά τη μεταφορά της βάσης ενός 
forum (vBulletin συγκεκριμένα). Τελικά έφταιγαν δύο πράγματα:

1. Πολλά fora έχουν την κακή συνήθεια στις οδηγίες εγκατάστασης να μην 
τονίζουν πόσο σημαντικό είναι το collation της βάσης. Στις παλιές MySQL, πριν 
την 4.1 αν δεν απατώμαι, το default charset ήταν latin1. Κρίνοντας από τα 
μηνύματα που σου επέστρεψε η mysql, η βάση σου μάλλον ήταν σε latin1 
collation, ενώ το forum σου λειτουργούσε σε iso8859-7. Υπό αυτές τις συνθήκες 
το φόρουμ λειτουργεί μια χαρά, αφού και τα δύο encodings είναι 8-bit και 
υπάρχει ένα-προς-ένα αντιστοιχία ανάμεσα στα δύο encodings. Απλά η βάση 
νομίζει ότι είναι latin1 αυτά που έχει μέσα, ενώ το forum τα χρησιμοποιεί ως 
iso8859-7. 

	Το παραπάνω σενάριο λειτουργεί μια χαρά, μέχρι που χρειάζεται να κάνεις 
mysqldump, αφού έχεις αναβαθμίσει τη MySQL σου σε 4.1+. Το mysqldump στις 
νεότερες εκδόσεις της MySQL χρησιμοποιεί UTF-8, οπότε η βάση του «μεταφράζει» 
αυτά που (νομίζει ότι) είναι latin1 σε utf8. Σε αυτό το σημείο προκύπτουν τα 
αλλαμπουρνέζικα που βλέπεις στα μηνύματα λάθους. Για να το δεις στην πράξη, 
πάρε το 
	ERROR 1062 (23000) at line 179520: Duplicate entry 'åîåôüóåùí' for key 1
και κάνε (σε μηχάνημα με utf8 locale)
	$ echo  'åîåôüóåùí' | iconv -f utf-8 -t iso8859-1 | iconv -f iso8859-7 -t 
utf8
Θα προκύψει η (ανορθόγραφη) λέξη "εξετόσεων". Ομοίως οι άλλες λέξεις 
είναι "ΜΡΟΥΜΙΔΗΣ" και "εμμανουηλ".

Με την αλυσίδα αυτή των iconv γίνεται η ακριβώς αντίστροφη διαδικασία από αυτή 
που έκανε η mysql και το mysqldump.

**Για να επιβεβαιώσουμε ότι όντως έτσι έγιναν τα πράγματα, κάνε ένα `grep "SET 
NAMES" dump.sql' και ένα `grep "CHARSET=" dump.sql'. Λογικά θα πρέπει να βρει 
ένα SET NAMES utf8 και πολλά CHARSET=latin1.**


2. Πέρα από το encoding havoc, τα διάφορα fora, απ' ότι έχω καταλάβει (αν και 
με ξενίζει πολύ), προκειμένου να ελαχιστοποιήσουν το hammering της βάσης κατά 
τη λειτουργία τους, φτιάχνουν το search index με έναν incremental τρόπο και 
χωρίς να ελέγχουν για duplicate keys. Αυτό μάλλον εξηγεί το θέμα του 
duplicate entry. Η λύση που είχα βρει τότε (ή μάλλον, το workaround), ήταν 
απλά να αφαιρέσω από το sqldump τελείως τα INSERT INTO 
πίνακας_του_search_index και να το ξαναφτιάξω αφού κάνω import τη βάση, 
χρησιμοποιώντας τα εργαλεία του forum.

Ανακεφαλαιώνοντας, εδώ υπάρουν 2 προβλήματα: το 1ο είναι ότι έχει αλλοιωθεί η 
κωδικοποίηση χαρακτήρων της βάσης, κάτι το οποίο θα διαπίστωνες αφού έκανες 
restore τη βάση, και εφόσον η νέα mysql σου χρησιμοποιεί utf8. Το 2ο είναι 
ότι ενδεχομένως εν γένει υπάρχουν duplicate entries στο search index του 
forum. Για να διορθώσεις το 1ο, κάνε τα εξής:

cat dump.sql | iconv -f utf-8 -t iso8859-1 | iconv -f utf-8 -t iso8559-7 > 
dump-fixed.sql

Μετά άνοιξε το sql-fixed.dump και αντικατάστησε όλες τις εμφανίσεις 
του 'CHARSET=latin1' με 'CHARSET=greek'.

Αν μετά από αυτό εξακολουθείς να μην μπορείς να κάνεις import, τότε θα πρέπει 
να σβήσεις όλες τις γραμμές που ξεκινάνε με 
INSERT INTO phpbb_search_wordlist
και να κάνεις rebuild το search index offline

Αυτά, ελπίζω να βοήθησα

Απόλλων




More information about the Linux-greek-users mailing list