Page MenuHomePhabricator

Encoding issues with externallinks tables
Closed, DeclinedPublicBUG REPORT

Description

Having an issue with the encoding of the externalllinks dumps, which seem to be latin1 instead of utf-8, which I think is what is expected.

Steps to reproduce
Using standard python3 installation on stat1004 machine. As far as we can tell, this applies to other dates / languages too.

import gzip

# this doesn't work (utf-8 encoding)
with gzip.open('/mnt/data/xmldatadumps/public/enwiki/latest/enwiki-latest-externallinks.sql.gz', 'rt') as fin:
    for line in fin:
        continue

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/usr/lib/python3.7/codecs.py", line 322, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd1 in position 406: invalid continuation byte

# this works just fine:
with gzip.open('/mnt/data/xmldatadumps/public/enwiki/latest/enwiki-latest-externallinks.sql.gz', 'rt', encoding='latin1') as fin:
    for line in fin:
        continue

Event Timeline

External links are liable to have some non-utf 8 in there in places. That is the case here; the line in question is

INSERT INTO `externallinks` VALUES (1123588,4589236,'http://www.mercksource.com/pp/us/cns/cns_hl_dorlands.jspzQzpgzEzzSzppdocszSzuszSzcommonzSzdorlandszSzdorlandzSzdmd_p_32zPzhtm#12663929',
....
(1130622,4614264,'http://ru.wikipedia.org/wiki/Википедия:Критерии_быстрого_удаления','http://org.wikipedia.ru./wiki/Википедия:Критерии_быстрого_удаления','http://org.wikipedia.ru./wiki/Википедия:Крите�'),
...
(1130988,4614264,'http://ru.wikipedia.org/wiki/Обсуждение_участника:Dj_shoo','http://org.wikipedia.ru./wiki/Обсуждение_участника:Dj_shoo','http://org.wikipedia.ru./wiki/Обсуждение_учас�')

You can see that the last character has been truncated in the middle of a byte sequence. That's invalid utf8 of course, leading the decoder to complain about it.
If you have a look at the entry in the external links table directly, you see

wikiadmin@10.64.32.13(enwiki)> select * from externallinks where el_id = 1130988;
+---------+---------+------------------------------------------------------------------------------+-------------------------------------------------------------------------------+--------------------------------------------------------------+
| el_id   | el_from | el_to                                                                        | el_index                                                                      | el_index_60                                                  |
+---------+---------+------------------------------------------------------------------------------+-------------------------------------------------------------------------------+--------------------------------------------------------------+
| 1130988 | 4614264 | http://ru.wikipedia.org/wiki/Обсуждение_участника:Dj_shoo                    | http://org.wikipedia.ru./wiki/Обсуждение_участника:Dj_shoo                    | http://org.wikipedia.ru./wiki/Обсуждение_учас�                |
+---------+---------+------------------------------------------------------------------------------+-------------------------------------------------------------------------------+--------------------------------------------------------------+
1 row in set (0.00 sec)

so it's right there in the database.

Thanks @ArielGlenn for looking into this. I did some more digging and it might relate to this issue: T108434

So at least with externallinks, until these are all cleaned up, we just have to accept decode errors? I know very little about encodings but is there anyway to fix the encoding issues in the dumps even if the databases maintain the original encoding?

@Isaac I think the other issue you linked to is only tangentially related; these links in the table were truncated due to field length I suppose, rather than acrtually using latin1. The way forward I think is to make sure that truncation of fields is done at character and not byte boundaries, and then go back and force a regeneration of the links table entries for the broken entries. Editing the dumps on the fly would be prohibitively expensive, requiring an extra pass over every row. But you might be able to get away with tossing the last byte out of such rows and then trying the utf8 conversion again, in your script.

@ArielGlenn thanks for explaining. So no simple fix. Unfortunately for us, the encoding part is enforced deep within Python's csv library (that we need to use for other reasons) so it's not easy to tweak. But the number of mis-encoded rows is hopefully sufficiently few that we can swallow the errors for now. Knowing that the URLs in the externallinks table might be truncated also makes me less interested in perfectly decoding them because they won't actually represent what's stored in the wikitext anyways.

Feel free to decline or resolve this ticket as desired then. Thanks!

I"ll go ahead and decline it then. You're likely right that the best thing to do is toss the bad urls since, as you say, they don't link to anything. And hopefully having this task around will save someone else time and energy when they run into similar errors. Thanks again for reporting!