The GitHub Availability Report
github.blog
github.blog
So that's them striving for two nines most of the time, which seems to be a fancy way of saying one nine. Be careful you're not setting the bar too high!
99% availability effectively becomes the weakest link in the chain. Would they still have pushed this report out if they phrased it as "...where GitHub was only down for an hour for every 99 hours of uptime"
But even that seems preventable.
CPU overloading, without memory starvation, can have a similar effect, though that doesn't tend to fall off the same efficiency wall as when IO is the issue (unless something has literally kicked off a fork bomb) because of the orders of magnitude differences in latency and work throughput.
I have started looking at tying together clusters of business apps that each have independent SQLite datastores using an application-level protocol for replication & persistence (over public HTTPS). This allows for really flexible schemes which can vary based upon the entity being transacted. With hosted SQL offerings, you are typically stuck with a fairly chunky grain for replication & transactions. If you DIY, you can control everything down to the most specific detail.
For instance, when going to persist a business object's changes, you can have a policy configured that reflects over the type and determines how many nodes need to be replicated to and which ones should replicate synchronously vs asynchronously based upon it. Log entries may only be async to 2 nodes, but you may decide that any accounting transactions should be replicated to 2 near nodes synchronously, with 2 more far nodes being async.
Additionally, you could inspect various business facts in the entity (or session related to the transaction) in order to determine ideal persistence strategy. One powerful example here could be to use a user's zip code to determine the geographically-ideal node to store the primary replica of their account & profile data. This could allow for lower latency access for that specific user.
I am out of touch of what is available in the NoSQL side of things but about 5 years ago there were too many things which had a terrible failure mode somewhere in the stack thus I'm never sure which way to go instead.
Modern relational databases are great at what they do.
At some point you get to machine sizes that won't fit in AWS as an example.
Ugh, I'm totally going to sympathize with whoever eventually joins your company after you've left who has to own this.
I'd be happy to offer a hypothetical if you are interested in debating the merits of my approach.
a shared database table’s
auto-incrementing ID column
exceeded the size that can
be represented by the MySQL
Integer type
Followed by: GitHub’s monitoring systems
currently alert when tables
hit 70% of the primary key
size
So why was there no alert?Or, I'm wrong. Maybe there wasn't an alert, or maybe the alert was ignored.
They don't unambigously say that the table with the primary key was the one rejecting the data, and they do say « We are now extending our test frameworks to include a linter in place for int / bigint foreign key mismatches. »
So perhaps the primary key itself was 64 bit, but a column referring to that key in a different table was mistakenly 32 bit.
Had the same thing happen in my company earlier this year in our homemade chat system.
Why didn't they get alerts? Because the alert was probably counting existing items in the table, not deleted elements that did increase the auto increment.
Projects started in the last three years that I've collaborated/been part of have all ditched the auto incremental IDs.
I'm not fully aware of the merits of either approach, so I'm just putting the info I have at hand out there.
However, at least two of these cases are actually something that I test for as part of the practise of systems administration at large high throughput companies.
Transaction ID wrap-around (and auto-increment capacity) are known-knowns in database administration;
The CPU starvation and flap detection mechanisms are also known-knowns in systems administration.
The premise that they came out of the left field is disengenuous at best;
unless I have "special experiences", which is possible I suppose as I was responsible for 1% of all web-traffic at one point in my life... but github should be much higher than that, I am surprised that they haven't tested the first principle assumptions, and controlled for them.
Similar to how a developer sprinkles code with asserts to ensure things that are impossible remain impossible; a sysadmin doesn't take for granted that a service will 'be magic'.
Or, if they do, why were they not in on the design meetings? Or, if they were, why were they ignored?
It seems that MySQL seems somehow connected to all the outages, especially the unexpected crashes.
>GitHub’s monitoring systems currently alert when tables hit 70% of the primary key size used. We are now extending our test frameworks to include a linter in place for int / bigint foreign key mismatches.
In 2020, should we have Integer(32-bit) primary keys anymore? I think at this time, everyone should just go with BigInt or UUID for primary keys/foreign keys, and basically not have running out of key space be an issue you have to worry about.
UUID PRIMARY KEY DEFAULT uuid_generate_v1mc()
In Postgres. It will give you UUIDs and the larger keyspace, without being excessively random (they're basically almost sequential). I do this always, even if the table has other int columns that look like friendly values that could be used as PKs. Some time in the future they will ruin your day."This function generates a version 1 UUID. This involves the MAC address of the computer and a time stamp. Note that UUIDs of this kind reveal the identity of the computer that created the identifier and the time at which it did so, which might make it unsuitable for certain security-sensitive applications."
I guess that's not immune to problems either (i can imagine problems with both mac address and time).
What would the B+Tree look like for over 2 billions UUIDS where there is no order within? Also, the cache locality problem.
A 64 bit int is enough for a single server. If a 64 bit int PK is exhausted, the data used to store the keys alone would require 128 exabytes, or in perspective, a SAN with 6.4 million 20tb hdds. Then you need several times that to store any kind of meaningful data
If you need to use UUIDs for other reasons such as a high degree of unique keys between servers that do not coordinate, then go for it, but not for the key size.
Nitpick: It's actually 7.38 million disks since "20 TB" for a disk means terabyte, not tebibyte.
edit: This explains it a bit
> When you insert a new row with a random primary key value, InnoDB has to find the page where the row belongs, load it in the buffer pool if it is not already there, insert the row and then, eventually, flush the page back to disk. With purely random values and large tables, all b-tree leaf pages are susceptible to receive the new row, there are no hot pages. Rows inserted out of the primary key order cause page splits causing a low filling factor. For tables much larger than the buffer pool, an insert will very likely need to read a table page from disk. The page in the buffer pool where the new row has been inserted will then be dirty. The odds the page will receive a second row before it needs to be flushed to disk are very low. Most of the time, every insert will cause two IOPs – one read and one write. The first major impact is on the rate of IOPs and it is a major limiting factor for scalability. [1]
1: https://www.percona.com/blog/2019/11/22/uuids-are-popular-bu...
What massive performance impact? You'd have one extra IOP, total, as it loaded the page for the new mac address, and then it would carry on as normal. It would be no different from when a sequential ID crosses a page boundary.
As part of maturity model, every product should have periodic milestones base on their scale where engineers should reassessment their infrastructure and the choices they made earlier. But, you can always overlook things unless you have a checklist for everything.
This is interesting. I wonder if they query the key size every N seconds as part of their monitor, or if they report the key size to the monitor on write.
Yeah that seems sane. The odds of you exceeding your monitoring threshold in 1 interval seems close to impossible too. Such as going from 70% to 100% in 30 seconds or whatever your monitor interval is set to.
As a devoted customer and a big fan of GitHub, it’s devastating to see service interruptions and our business impacted by these problems; as the team behind TiDB, we (PingCAP) believe there is something we can do to help solve the database high availability and scalability problem. We would like to propose the database team in GitHub to consider the TiDB platform. TiDB and TiKV can work as a scale-out MySQL and it has been battle-tested in all kinds of hyper-scale scenarios.
Additionally, just in case you didn’t do this, we also recommend GitHub considering the Chaos-Mesh project (https://github.com/pingcap/chaos-mesh) to do Chaos Engineering. Chaos Mesh was our internal chaos engineering platform and we open-sourced it on Dec. 31, 2019. It can be used for simulating different kinds of failures including network partition, flaky disk, node outage. You can easily use it to simulate failures in a test environment and confirm that the high availability works as expected.
ithkuil is not asking if you can change the length of the integer column but rather if you somehow would have prevented the issue GitHub saw here with hitting the limit. So something like automatically updating the length, or giving the developers warnings, or alerts of some sort.
My guess would be no, as I haven't seen this in the wild.
And if the answer is indeed "no", your comment seems again to plug something that wouldn't actually solve the problem GitHub saw here.
Furthermore, I wonder how long does it take to enlarge a pk column using alter table on a database that has a significant fraction of 4 billion rows?
EDIT: I'm not arguing that github would not benefit from TiDB; they might be genuinely better of with it on many fronts. I just wonder if it's fair to plug a product this way
For the following question, the answer is in seconds. To enlarge the column length, TiDB just need to modify the meta data. "how long does it take to enlarge a pk column using alter table on a database that has a significant fraction of 4 billion rows?"
> There is not automatically way to enlarge the length
> I think that is not the things should be done by the database itself
> would be helpful to show a warning to DBA
So, in the end, TiDB does nothing to actually solve the problem they experienced but you still feel comfortable offering them your own solution? Sounds like you're a VP of Marketing, not a VP of Engineering. Leaves a very sour taste when spamming a forum like this. I hope your bosses don't read HN and sees your comments plugging TiDB everywhere where it's not relevant.
thanks, that's interesting. So existing data using the previous 32-bit encoded values happily coexist with the new data being written after the migration?
Sorry; it's hard to balance terseness with clarity. What I meant is to ask whether a tool such as Chaos-Mesh could have helped the github operations team to be aware of such a failure mode by causing this kinds of problems early.
I think that's the purpose of chaos-engineering right? Some things happen too infrequently for us to plan for them, until when they finally do, causing problems that are more costly to solve than the cost of the prevention.
It's still unclear to me whether this particular failure mode is common enough to be part of what a chaos-engineering tool explores by default; after all, not all databases around contain billions of rows. If engineers have to explicitly enable such a test because they are afraid of what would happen if a PK overflows, well, then probably they would take other preventive measures so that the problem doesn't happen in the first place (either preventively upgrading the size of the counter, or at least put some monitoring). I think what happened here is that a solution was designed when the database was way smaller; the user base grew and grew and this particular failure mode was overlooked (because there are many many other things to care about!).
(I write this because I'm genuinely curious about what other people think about this topic, not to bash on parent for a shameless plug; I mentioned that only as a side comment; I heard good things about TiDB, I wish you well)
It is very common. Had the same thing happen in my company last year, on multiple systems! The organization was reaching a decade old, nobody thought of that when the table were initially created.
So while the reward of you promoting your product on HN can be high, unless it's very specific and actually solves their need, it just looks spammy.