MySQL: Duplicate entry for key
Panagiotis Palias
palias at ath.forthnet.gr
Wed Sep 5 01:49:39 EEST 2007
Apollon Oikonomopoulos wrote:
> Καλημέρα,
>
> Τυχαίνει να έχω αντιμετωπίσει το ίδιο πρόβλημα κατά τη μεταφορά της βάσης ενός
> 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.**
Το ότι δε μου έβγαλε τίποτα είναι ανησυχητικό;
Το grep δε βρήκε τα patterns μέσα στη βάση.
> 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
cat phpbb_db_backup.sql | iconv -f utf-8 -t iso8859-1 | iconv -f
iso8859-7 -t utf-8 > dump-fixed.sql
iconv: illegal input sequence at position 2491
η γραμμή 2491 περιέχει το εξήςINSERT INTO phpbb_banner_stats (banner_id,
click_date, click_ip, click_user, user_duration) VALUES('1',
'1077183641', '8d1d262c', '-1', '3
752');
>
> Μετά άνοιξε το sql-fixed.dump και αντικατάστησε όλες τις εμφανίσεις
> του 'CHARSET=latin1' με 'CHARSET=greek'.
>
> Αν μετά από αυτό εξακολουθείς να μην μπορείς να κάνεις import, τότε θα πρέπει
> να σβήσεις όλες τις γραμμές που ξεκινάνε με
> INSERT INTO phpbb_search_wordlist
> και να κάνεις rebuild το search index offline
>
> Αυτά, ελπίζω να βοήθησα
>
> Απόλλων
Βάσει όλων αυτών ξέρεις τι μπορεί να συμβαίνει ή όπως λες είναι χαμένη
υπόθεση και να προσπαθήσω να σβήσω τις insert στο phpbb_search_wordlist;
Ευχαριστώ για τον κόπο και τη βοήθεια!
More information about the Linux-greek-users
mailing list