LMS-PLUS udostępnia skrypt do konwersji Konwersja bazy danych LMS z MySQL na PostgreSQL, ale jest on dość wolny z uwagi na jednowątkowość. Co przy dużych bazach danych może być problemem.
W moim przypadku wybór padł na pgloader, który wykonał konwersję w 3 minuty, a nie 5h z wykorzystaniem w/w skryptu. Poniżej krótka relacja i moje wskazówki dla zainteresowanych.
Po latach użytkowania baza MySQL urosła i z różnych przyczyn zgromadziła wiele niespójnych danych. Najwięcej zabawy było z doprowadzeniem bazy MySQL do stanu, w którym pgloader nie raportował błędów. Sama konwersja jest bardzo szybka.
Dlaczego pgloader?
- Wykorzystuje wszystkie rdzenie, bo jest wielowątkowy.
- Kopiuje dane w locie z działającej bazy MySQL do PostgreSQL.
- pgloader uses the PostgreSQL COPY protocol which implements a streaming to send data in a very efficient way.
Napotkane problemy z MySQL:
ERROR: invalid byte sequence for encoding “UTF8”: 0x00
#sprawdzamy co tam w trawie piszczy
SELECT * FROM cash WHERE comment LIKE CONCAT("%", CHAR(0x00 using utf8), "%");
#jak coś znajdzie lepiej to poprawić przed konwersją np.:
UPDATE cash SET comment = REPLACE(comment,CHAR(0x00 using utf8),' ');
UPDATE cash SET comment = REPLACE(comment,'ł','Ł');
#sprawdzamy co tam w trawie piszczy
SELECT * FROM cashimport WHERE description LIKE CONCAT("%", CHAR(0x00 using utf8), "%")
#jak coś znajdzie lepiej to poprawić przed konwersją np.:
UPDATE cashimport SET description = REPLACE(description,CHAR(0x00 using utf8),' ');
UPDATE cashimport SET customer = REPLACE(customer,CHAR(0x00 using utf8),' ');
# ewentualnie jeszcze
UPDATE cashimport SET customer = REPLACE(customer,'Å','Ł');
UPDATE cashimport SET customer = REPLACE(customer,'Ó','Ó');
UPDATE cashimport SET description = REPLACE(description,'Å','Ł');
UPDATE cashimport SET description = REPLACE(description,'Ó','Ó');
Konwersja bazy to jedno, a potem trzeba modyfikować wszystkie dodatki i skrypty, jeżeli działały tylko w oparciu o bazę MySQL.
MySQL | PostgreSQL |
---|---|
UNIX_TIMESTAMP() | extract(epoch from now()) |
IF (passwd = ”, ‘mojehaslo’, passwd) AS value | CASE WHEN passwd IS NULL THEN ‘mojehaslo’ ELSE passwd END AS value |
FROM_UNIXTIME(assignments.dateto) | to_timestamp(assignments.dateto) |
MONTH(to_timestamp(creationdate)) | EXTRACT(MONTH FROM customers.creationdate) |
Przydatne linki:
https://codebeautify.org/sqlformatter
https://mariadb.com/kb/en/setting-character-sets-and-collations/