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