Re: Why Uber Engineering Switched from Postgres to MySQL
ayende.com
ayende.com
[0]: https://github.com/jpsingleton/ANCLAFS/pull/12
I wonder if part of the problem is really Linux, not Postgres and that another way they could have addressed this is by trying FreeBSD (which is what a lot of people run Postgres on).
I'm not a PostgreSQL expert but it seems like it has a different philosophy with OS filesystem buffering.
Using Oracle and MS SQL Server as counterexamples... you can configure Oracle to bypass os filesystem buffers by using "raw" disk io. With MS SQL Server, it opens datafiles with CreateFile(,,,FILE_FLAG_NO_BUFFERING) to bypass the Windows NTFS caching. (Microsoft recently ported SQL Server to Linux so not sure what combination of techniques they are doing on there since CreateFile(FILE_FLAG_NO_BUFFERING) is a Win32 api and not relevant to Linux.)
The closest approximation PostgreSQL has is the "shared_buffers" parameter but from the documentation[1] I've read, the best practice for that setting is 25% to 40% of main memory. In contrast, Oracle and MS SQL Server db engines with their self-managed buffer pools are designed to use almost 100% of the main memory.
Conclusion: PostgreSQL relies on the os filesystem cache and its own db buffer does not supersede the os buffers. Other db engines' buffer pools are designed to bypass the os filesystem cache.
Installing PostgreSQL on FreeBSD instead of Linux wouldn't drastically change the recommended range for "shared_buffers".
[1]https://www.postgresql.org/docs/9.1/static/runtime-config-re...
Open options:
int f = open("your file", O_DIRECT|O_DSYNC|O_RDWR);
O_DIRECT signals that a file descriptor should by-pass kernel level caching and write directly to the device.O_SYNC signals that a file descriptor calls should not return until all data+metadata has been synced with disk.
O_DSYNC does the same as O_SYNC but doesn't force meta-data synchronicity before the block ends.
Related Stack Overflow https://stackoverflow.com/questions/5055859/how-are-the-o-sy...
Related LWN article https://lwn.net/Articles/457667/
I have no idea if this is true or not though.
Linux does not have the same meta-data knowledge that the native cache has. There is a layering problem which makes it hard to add this. For example: after some page splits and fragmentation pages are no longer stored in physical order. How can a logical read ahead work on the Linux level?
http://nickcraver.com/blog/2016/02/17/stack-overflow-the-arc...
By analogy, it is similar to how a purpose-designed hash map will almost always significantly outperform a generic hash map. There are enough design knobs that perfect foreknowledge of the use case allows significant optimization of the implementation.
Yes, mmap would presumably be preferable in most situations, but pread would seem to be universally preferable to an lseek and read. I assume the kernel keeps per-fd statistics on sequential reads anyway, so for long-lived fds, lseek presumably wouldn't provide any better read-ahead hinting than pread.
This is not true in general: there are circumstances where Postgres can skip updating indexes when a tuple is updated, assuming the update only changes values in non-indexed columns. See:
http://pgsql.tapoueh.org/site/html/misc/hot.html
https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f...
Every time a new order is created the status flows from
* unassigned
* assigned
* passenger on board
* completed
That should really be an event stream, but if you want to find all `unassigned` orders, an index would be good.
We had a similar problem with this kind of table, at much lower volume than uber.
But only when there was a two column index
`status, pickup time`
Or
`status, created at`
No, an index is not good for that, because it only has 4 values (at most 4 times faster than a full table scan), and it hammers the index on every update, using PostgreSQL or not.
Same for the two column index: single column indexes on pickup time and creation time are highly selective, and their values are updated basically never, whereas status has low selectivity and updates are common: combining them you don't significantly improve selects on the two columns, and limit the performance edge on time select where time.
Status index only performs well when you select one of the values which is is significantly underrepresented in the column (e.g. all except completed). The most performing approach without doing black magic is to split in columns with separate indexes: Assigned Time, Pickup Time, Completed Time. If you want unassigned ones, you select where Assigned Time IS NULL, same for the other columns. Performance on update for most RDBMS blasts, as index updates are now distributed among several, allowing higher concurrency and overall throughput.
"Matt Ranney at All Your Base 2015"
https://vimeo.com/145842299 ( 30 min )
keywords: Uber + PostgreSQL + Chaos Monkey-style failure testing
"WHAT WILL I LEARN?
After this talk, you’ll be able to better assess the risk from the different failure modes of databases in your system’s architecture."
Moving $10 from Bob's account to Jack's involves:
1. Inserting a transaction to remove $10 from Bob's account
2. Inserting a transaction to add $10 to Jack's account.
Both 1 and 2 must succeed or fail in total if either of them fail (or both).
You can imagine the disaster in banking apps, ERPs and other financial systems when 1 succeeds but 2 fails and the database is happy with that imbalanced state.
On the other hand PostgreSQL is ACID compliant from the beginning. And PostgreSQL adds new features every few months. Some of these features that do not exist in MySQL are; IP address data type, serial fields (multiple auto-increments), row level permissions, geographical data types, inheritance, XML data type, custom data types, range data type and things that I don't know but I know that it provides many features of SQL language like intersect, except and merge joins. It is like free Oracle.
It's just much more commonly used in .NET apps.
Therefore, maybe a reasonable compromise is to put "Ayende" at the end like this:
"Why Uber Engineering Switched from Postgres to MySQL (Ayende's comments)"
I don't, and I don't know how many do. Do you?
I always check the domain name because I know despite a catchy title, some domains are not worth checking.
Whilst on reddit and other sites I will check the domain, on HN they are posted so infrequently that I spare myself the strain.
Yes I understand that that was the intention but let's suppose the process of detecting domain name in the title had been automated. The post would've been flagged.
>on HN they are posted so infrequently
I take it you don't browse HN's newest page, it's full of garbage links.
From the back & forth comments, I'm getting the vibe that the submitter broke some hidden HN principle??? As if putting a person's name in the title is trying to manipulate the HN readers into hero worship?? Or trying to impress HN readers with Hollywood name dropping?? I read the "Ayende" using a perfectly neutral interpretation but it's obvious others are really turned off by it. I can't see any other reason for the bikeshedding about the title.
[1]https://www.google.com/search?q=eye+tracking+gui&source=lnms...
I agree that OP did it to differentiate this response article from the original one but this was the first time the article was posted on HN so we don't really know if it needed to be differentiated (i.e. if it had been posted without getting to the frontpage then it would've been safe to assume the necessity of a different title).
Either ways I think "A response to" instead of "Ayende on" would've done the same job without risking falling into any of the pitfalls you mentioned. But enough nitpicking, the article in itself is interesting.
I thought it worthy of posting since Ayende heads up RavenDB and knows a thing or two about databases and their low level implentation
/sarcasm
I only wish LE would treat CAN-SPAM seriously and put more sources into criminal enforcement.