Live data from Hacker News

What happened to Vivaldi Social?

thomasp.vivaldi.net

71–80 of 83 posts

Re: What happened to Vivaldi Social?

#71
post #58
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.

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 result…

It looks to me like using empty string would not have prevented the bug in the article. If their language had maybes, they might be able to prevent this bug by having a function type signature where uri is concrete. And most langs with maybes will automatically turn external nulls into maybes.

Re: What happened to Vivaldi Social?

#72
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…

NULL is inevitable if you use JOINs, simply as a matter of what a JOIN is.

More deeply, NULL is inevitable because reality is messy and your database can't decline to deal with it just because it's messy. You want to model titles, with prenomials and postnomials, and then generate full salutations using that data? Well, some people don't have postnomials, at the very least, so even if you never store NULLs you're going to get them as a result of the JOIN you use to make the salutation.

You can remove the specific NULL value, but you can't remove the fact "Not Applicable"/"Unknown" is very often a valid "value" for things in reality, and a database has to deal with that.

Re: What happened to Vivaldi Social?

#73
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.

> What's the alternative, an empty string?

Yes! NULL is relational for “don’t know”, and SQL is (mostly, with varying degrees of success) designed to treat is as such. That’s why NULL=anything is NULL and not e.g. false (and IMO it’s a bit of a misfeature that queries that branch on a NULL don’t crash, although it’s still better than the IEEE 754 NaN=anything outright evaluating to false). If the value is funky but you do know it, then store a funky value, not NULL.

Re: What happened to Vivaldi Social?

#74

Earlier quoted context omitted.

> In that case, the stack trace misses the most important thing: which datum failed. OK we agree that the stacktrace isn't _enough_, but it's still a really useful thing to have to understand what exactly happened (and quite often the single most useful thing). Of course we still expect devs to capture the information that led to the `log.Error`, so that we don't have to play guess games. Rather than manually-annotat…

> I'd prefer getting rid of all logging altogether I prefer to build metrics and distributed traces from logs! But, I think we can agree that they're the same thing. It's a stream of events that a system captures and lets you retrieve. (I wrote our logging/tracing/metrics library at work, and indeed I call any sort of start/finish operation a Span. https://github.com/pachyderm/pachyderm/blob/master/src/inter... ) Pos…

> I prefer to build metrics and distributed traces from logs! But, I think we can agree that they're the same thing. It's a stream of events that a system captures and lets you retrieve.

...

> Post-processing into an efficient retrieval system is the key. You can tail the logs and send span starts/ends to Jaeger, and you can tail the logs and send summarized metrics to Prometheus or InfluxDB.

I'm not sure it's the same thing; the idea that you spit everything out into this flat stream of bytes and then try to parse it back into structured data seems ass-backwards to me. I agree with keeping a trace of events that happen in your system, but if it's data you care about, don't you want to keep it structured the whole way through? At which point it's not really "logs" as usually understood.

Re: What happened to Vivaldi Social?

#75
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.

> What's the alternative, an empty string? Yes! NULL is relational for “don’t know”, and SQL is (mostly, with varying degrees of success) designed to treat is as such. That’s why NULL=anything is NULL and not e.g. false (and IMO it’s a bit of a misfeature that queries that branch on a NULL don’t crash, although it’s still better than the IEEE 754 NaN=anything outright evaluating to false). If the value is funky but y…

But a known value of empty string is a fairly commonplace thing, and I have never wanted to treat that as null.

Re: What happened to Vivaldi Social?

#77
post #5

This make anyone elses eyebrows raise sky high at this? > Claire replied, asking for the full stacktraces for the log entries, which I was able to also extract from the logs. This is either deep voodoo magic, or the code or configuration is turning a Xeon into the equivalent of a 286. House is that not, like, megabytes on every single hit?

You’ve confused a stack trace with a core dump (or something similar).

Re: What happened to Vivaldi Social?

#78

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)

Yes you shouldn't be manually restoring sql dumps but I've been working in this field long before versioned source control or pgbackrest existed.

Re: What happened to Vivaldi Social?

#79
post #10
post #3

Items two and three not happening atomically feels like an issue, though I assume there's a reason that it's not trivial to do so (I haven't looked at the code; really should at some point.)

One of the linked fixes is: https://github.com/mastodon/mastodon/commit/13ec425b721c9594... It seems like it was trivial to make it happen atomically. There just wasn't a need to before since them not being atomic isn't an issue, unless you have a poor configuration like someone pointing sidekiq at a stale database server (sorry, a replica), which I see as the primary issue here.

OTOH, reading from a read-only copy reduces load on the master

Re: What happened to Vivaldi Social?

#80
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.

At scale ... it is better to use CQRS ... sou you have a transaction model which is fully normalized and a read nly model which is wide, if you really want to use a RDBMS.
Post reply on HN