Live data from Hacker News

What happened to Vivaldi Social?

thomasp.vivaldi.net

51–60 of 83 posts

Re: What happened to Vivaldi Social?

#51
post #27

Great writeup (including the human cost, e.g. loss / lack of sleep, which in my experience has a huge impact on complicated incident resolution). Here’s what jumped out at me: “The new account was created in our database with a null value in the URI field.” Almost every time I see a database-related postmortem — and I have seen a lot of them — NULL is lurking somewhere in the vicinity of the crime scene. Even if NULL…

I finally made an account just to respond to this, I hope you don't find that too aggressive a move.

Null is a perfectly valid value for data, and should be treated as such. A default value (e.g. -1 for a Boolean or an empty for a string) can make your system appear to work where NULL would introduce a runtime error, but that doesn't mean your system is performing as expected, it just makes it quieter.

I know it's tempting to brush NULL under the rug, but nothing is just as valid a state for data as something, and systems should be written generally to accommodate this.

Re: What happened to Vivaldi Social?

#52

I'll never forget the first time I had to restore a massive sql dump and realized that vim actually segfaults trying to read it. That's when I discovered the magic of spit(1) "split a file into pieces". I just split the huge dump into one file per table. Of course a table can also be massive, but at least the file is now more uniform which means you can easier run other tools on it like sed or awk to transform querie…

I'm surprised that vim segfaults! I had it slow to open huge files, but I always assumed it could handle anything, through some magic buffering mechanisms. I could be wrong!

That being said, from the point that one has to edit the dump to restore data... something is very wrong in the restore process (the knowledge of which isn't helpful when you're actually faced with the situation, of course)

Re: What happened to Vivaldi Social?

#53
post #25

> And it just so happens that all local accounts in a Mastodon instance have a null value in their URI field, so they all matched. How? NULL = NULL evaluates to FALSE, SQL is a three value logic, specifically Kleene's weak three-valued logic, NULL anyoperator NULL is NULL.

Yeah, was wondering. Maybe they filter at the application level? And check equality with their language's null value?

This is the case, more or less. The fix for this issue boiled down to a one-liner: https://github.com/mastodon/mastodon/commit/13ec425b721c9594...

But basically, some object attributes (which should have been set by default) weren't set by default. This is a common oversight when dealing with data structures that are incomplete at one point or another, and it's easy to assume during programming that code will execute in a fixed order that allows for the necessary fields to be present when needed although sometimes it doesn't always work out that way.

In my opinion, they were lucky to have caught this but a fix should include more than adding missing initialization. They should implement a sanity check to ensure that fields used are present and !NULL, and if things are undefined or missing for whatever reason, abort whatever process they are attempting to perform and log the issue.

Re: What happened to Vivaldi Social?

#54
post #46

Earlier quoted context omitted.

What's the alternative, an empty string? IMO the problem (at least in this case) is not NULL in the DB, but NULL at the application level. If NULL is some sort of Maybe monad and you're forced to deal with it, well, you're forced to deal with it, think about it, etc. Empty string, whatever NULL string is in your language of choice, or some sort of sigil value you invent... not much of a difference.

Joins are cheap. Wide tables are often a sign that a data-model is a bit too CRUDdy. Foreign key relationships often do a much better job modeling optionality/cardinality in relational systems. In this case, a `user_uris` table with non-nullable columns and a unique constraint on `user_id` is the first option that comes to mind.

I had a situation where I'm not really sure I could have used something else than null: I need a value in one of two columns exactly (meaning one is NULL and the other not).

You can build a constraint to check that if it's in the same table, but across tables it seems to be a bit more complex right ?

Re: What happened to Vivaldi Social?

#55
post #46

Earlier quoted context omitted.

What's the alternative, an empty string? IMO the problem (at least in this case) is not NULL in the DB, but NULL at the application level. If NULL is some sort of Maybe monad and you're forced to deal with it, well, you're forced to deal with it, think about it, etc. Empty string, whatever NULL string is in your language of choice, or some sort of sigil value you invent... not much of a difference.

A separate Boolean column?

Can't wait to have a NULL url and has_url TRUE.

Might or might not be based in production data I deal with on a daily basis.

Re: What happened to Vivaldi Social?

#56
post #46
post #27

Great writeup (including the human cost, e.g. loss / lack of sleep, which in my experience has a huge impact on complicated incident resolution). Here’s what jumped out at me: “The new account was created in our database with a null value in the URI field.” Almost every time I see a database-related postmortem — and I have seen a lot of them — NULL is lurking somewhere in the vicinity of the crime scene. Even if NULL…

What's the alternative, an empty string? IMO the problem (at least in this case) is not NULL in the DB, but NULL at the application level. If NULL is some sort of Maybe monad and you're forced to deal with it, well, you're forced to deal with it, think about it, etc. Empty string, whatever NULL string is in your language of choice, or some sort of sigil value you invent... not much of a difference.

[deleted]

Re: What happened to Vivaldi Social?

#57
post #46

Earlier quoted context omitted.

What's the alternative, an empty string? IMO the problem (at least in this case) is not NULL in the DB, but NULL at the application level. If NULL is some sort of Maybe monad and you're forced to deal with it, well, you're forced to deal with it, think about it, etc. Empty string, whatever NULL string is in your language of choice, or some sort of sigil value you invent... not much of a difference.

Joins are cheap. Wide tables are often a sign that a data-model is a bit too CRUDdy. Foreign key relationships often do a much better job modeling optionality/cardinality in relational systems. In this case, a `user_uris` table with non-nullable columns and a unique constraint on `user_id` is the first option that comes to mind.

For a table with a single column (plus FK), isn't LEFT JOIN isomorphic to just having a NULLABLE column (and much better at data locality)?

It might prevent error if you only rely on INNER JOIN but that's rarely the case at least for me (you often want to access the record anyways).

Much safer to deal with the NULL at the application level.

Re: What happened to Vivaldi Social?

#58
post #46
post #27

Great writeup (including the human cost, e.g. loss / lack of sleep, which in my experience has a huge impact on complicated incident resolution). Here’s what jumped out at me: “The new account was created in our database with a null value in the URI field.” Almost every time I see a database-related postmortem — and I have seen a lot of them — NULL is lurking somewhere in the vicinity of the crime scene. Even if NULL…

What's the alternative, an empty string? IMO the problem (at least in this case) is not NULL in the DB, but NULL at the application level. If NULL is some sort of Maybe monad and you're forced to deal with it, well, you're forced to deal with it, think about it, etc. Empty string, whatever NULL string is in your language of choice, or some sort of sigil value you invent... not much of a difference.

The problem is precisely that NULL is not some sort of Maybe monad, but people keep trying to use it as such. It's a lot like using NaN as a sentinel value for floats - sure, you can do that, but when something goes wrong, instead of an error at the point where the problem is, you end up dealing with a mysterious NULL somewhere way down the line. And that's the best case - the worst is that you get wrong query results because of the way NULL comparisons work.

An empty string is better as a sentinel value because at least this doesn't have the weird "unknown value" semantics that NULL does. But if you really want the same level of explicitness and safety as an option type, the theoretically proper way to do this in relational model is to put the strings themselves in a separate table in a 1:N (where N is 0 or 1) relationship with the primary table.

Re: What happened to Vivaldi Social?

#59
post #46
post #27

Great writeup (including the human cost, e.g. loss / lack of sleep, which in my experience has a huge impact on complicated incident resolution). Here’s what jumped out at me: “The new account was created in our database with a null value in the URI field.” Almost every time I see a database-related postmortem — and I have seen a lot of them — NULL is lurking somewhere in the vicinity of the crime scene. Even if NULL…

What's the alternative, an empty string? IMO the problem (at least in this case) is not NULL in the DB, but NULL at the application level. If NULL is some sort of Maybe monad and you're forced to deal with it, well, you're forced to deal with it, think about it, etc. Empty string, whatever NULL string is in your language of choice, or some sort of sigil value you invent... not much of a difference.

In this specific case, all the local users could have had URLs in the database instead of NULL (or empty string), which would have prevented them from merging.
Post reply on HN