Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can concurrent value modification impact single select in PostgreSQL 9.1?

Consider the following query executed in PostgreSQL 9.1 (or 9.2):

SELECT * FROM foo WHERE bar = true

Suppose it's a fairly long running query (e.g. taking a minute).

If at the start of the query there are 5 million records for which bar = true holds, and during this query in another transaction there are rows added and removed in the foo table, and for some existing rows updates are made to the bar field.

Will any of this affect the outcome of the above shown select query?

I know about transaction-isolation and visibility between separate statements in a single transaction, but what about a single statement that's running?

like image 649
dexter meyers Avatar asked Aug 24 '12 13:08

dexter meyers


People also ask

How many updates per second can Postgres handle?

When using Postgres if you do need writes exceeding 10,000s of INSERT s per second we turn to the Postgres COPY utility for bulk loading. COPY is capable of handling 100,000s of writes per second. Even without a sustained high write throughput COPY can be handy to quickly ingest a very large set of data.

How does select query work in PostgreSQL?

The PostgreSQL SELECT statement retrieves data from a single or several tables in a database, and returns the data in a result table, called a result-set. Use the SELECT statement to return one or more rows matching the specified criteria from the database tables.

Does PostgreSQL support concurrency?

This chapter describes the behavior of the PostgreSQL database system when two or more sessions try to access the same data at the same time. The goals in that situation are to allow efficient access for all sessions while maintaining strict data integrity.

What does the for update do on a select statement when a transaction has been started?

SELECT FOR UPDATE is a SQL command that's useful in the context of transactional workloads. It allows you to “lock” the rows returned by a SELECT query until the entire transaction that query is part of has been committed.


2 Answers

No.
Due to the MVCC model only tuples that are visible at query start will be used in a single SELECT. Details in the manual here:

Read Committed is the default isolation level in PostgreSQL. When a transaction uses this isolation level, a SELECT query (without a FOR UPDATE/SHARE clause) sees only data committed before the query began; it never sees either uncommitted data or changes committed during query execution by concurrent transactions. In effect, a SELECT query sees a snapshot of the database as of the instant the query begins to run. However, SELECT does see the effects of previous updates executed within its own transaction, even though they are not yet committed. Also note that two successive SELECT commands can see different data, even though they are within a single transaction, if other transactions commit changes during execution of the first SELECT.

Emphasis mine.

like image 62
Erwin Brandstetter Avatar answered Oct 07 '22 05:10

Erwin Brandstetter


The query will be a read-consistent view of the data as of the start of the query. In Postgresql, the documentation on Multi-Version Concurrency Control (MVCC) explains how it is done (multiple versions of a record exist in the table). In Oracle, the Sequence Change Number (SCN) is used along with "before-images" of modified data. Here is an old doc, Transaction Processing in Postgresql, with the section "non-overwriting storage management". But take a look at MVCC.

Or read the chapter on MVCC in the Postgresql doc

like image 36
Glenn Avatar answered Oct 07 '22 07:10

Glenn