Postgrex.start_link

You're seeing just the function start_link, go back to Postgrex module for more information.

Specs

start_link([start_option()]) ::
  {:ok, pid()} | {:error, Postgrex.Error.t() | term()}

Start the connection process and connect to postgres.

Options

Postgrex provides multiple ways to connect to the server, listed in order of precedence below:

  • :hostname - Server hostname (default: PGHOST env variable, then localhost);
  • :port - Server port (default: PGPORT env variable, then 5432);
  • :endpoints - A list of endpoints (host and port pairs); Postgrex will try each endpoint in order, one by one, until the connection succeeds; The syntax is [{host1,port1},{host2,port2},{host3,port3}]; This option takes precedence over :hostname+:port;
  • :socket_dir - Connect to PostgreSQL via UNIX sockets in the given directory; The socket name is derived based on the port. This is the preferred method for configuring sockets and it takes precedence over the hostname. If you are connecting to a socket outside of the PostgreSQL convention, use :socket instead;
  • :socket - Connect to PostgreSQL via UNIX sockets in the given path. This option takes precedence over the :hostname, :endpoints and :socket_dir;

Once a server is specified, you can configure the connection with the following:

  • :database - Database (default: PGDATABASE env variable; otherwise required);
  • :username - Username (default: PGUSER env variable, then USER env var);
  • :password - User password (default: PGPASSWORD env variable);
  • :parameters - Keyword list of connection parameters;
  • :timeout - Socket receive timeout when idle in milliseconds (default: 15000);
  • :connect_timeout - Socket connect timeout in milliseconds (defaults to :timeout value);
  • :handshake_timeout - Connection handshake timeout in milliseconds (defaults to :timeout value);
  • :ssl - Set to true if ssl should be used (default: false);
  • :ssl_opts - A list of ssl options, see the tls_client_option from the ssl docs;
  • :socket_options - Options to be given to the underlying socket (applies to both TCP and UNIX sockets);
  • :idle_interval - Ping connections after a period of inactivity in milliseconds. Defaults to 1000ms;
  • :target_server_type - Allows opening connections to a server in the given replica mode. The allowed values are :any, :primary and :secondary (default: :any). If this option is used together with endpoints, we will traverse all endpoints until we find an endpoint matching the server type;
  • :disconnect_on_error_codes - List of error code atoms that when encountered will disconnect the connection. This is useful when using Postgrex against systems that support failover, which when it occurs will emit certain error codes e.g. :read_only_sql_transaction (default: []);
  • :show_sensitive_data_on_connection_error - By default, Postgrex hides all information during connection errors to avoid leaking credentials or other sensitive information. You can set this option if you wish to see complete errors and stacktraces during connection errors;

The following options controls the pool and other Postgrex features:

  • :prepare - How to prepare queries, either :named to use named queries or :unnamed to force unnamed queries (default: :named);
  • :transactions - Set to :strict to error on unexpected transaction state, otherwise set to :naive (default: :strict);
  • :pool - The pool module to use, defaults to DBConnection.ConnectionPool. See the pool documentation for more options. The default :pool_size for the default pool is 1. If you set a different pool, this option must be included with all requests contacting the pool;
  • :types - The types module to use, see Postgrex.TypeModule, this option is only required when using custom encoding or decoding (default: Postgrex.DefaultTypes);

Postgrex uses the DBConnection library and supports all DBConnection options like :idle, :after_connect etc. See DBConnection.start_link/2 for more information.

Examples

iex> {:ok, pid} = Postgrex.start_link(database: "postgres")
{:ok, #PID<0.69.0>}

Run a query after connection has been established:

iex> {:ok, pid} = Postgrex.start_link(after_connect: &Postgrex.query!(&1, "SET TIME ZONE 'UTC';", []))
{:ok, #PID<0.69.0>}

Connect to postgres instance through a unix domain socket

iex> {:ok, pid} = Postgrex.start_link(socket_dir: "/tmp", database: "postgres")
{:ok, #PID<0.69.0>}

PgBouncer

When using PgBouncer with transaction or statement pooling named prepared queries can not be used because the bouncer may route requests from the same postgrex connection to different PostgreSQL backend processes and discards named queries after the transactions closes. To force unnamed prepared queries set the :prepare option to :unnamed.

Handling failover

Some services, such as AWS Aurora, support failovers. The 2 options endpoints and target_server_type can be used together to achieve a faster fail-over.

Imagine an AWS Aurora cluster named "test" with 2 instances. Use the following options minimize downtime by ensuring that Postgrex connects to the new primary instance as soon as possible.

{:ok, pid} = Postgrex.start_link(
  endpoints: [
    {"test.cluster-xyz.eu-west-1.rds.amazonaws.com", 5432},
    {"test.cluster-ro-xyz.eu-west-1.rds.amazonaws.com", 5432}
  ],
  target_server_type: :primary,
  (...)
)

In the event of a fail-over, Postgrex gets first disconnected from what used to be the primary instance. The primary instance will then reboot and turn into a secondary instance. Meanwhile, one of the secondary instances will have turned into the new primary instance. However, the DNS entry of the primary endpoint provided by AWS can take some time to get updated. That is why it can be faster to let Postgrex iterate over all the instances of the cluster to find the new primary instance instead of waiting for the DNS update.

If the cluster does not have DNS-backed primary and secondary endpoints (like the ones provided by AWS Aurora) or if the cluster is made of more than 2 instances, the hostname (and port) of all of the individual instances can be specified in the endpoints list:

endpoints: [
  {"test-instance-1.xyz.eu-west-1.rds.amazonaws.com", 5432},
  {"test-instance-2.xyz.eu-west-1.rds.amazonaws.com", 5432},
  (...),
  {"test-instance-N.xyz.eu-west-1.rds.amazonaws.com", 5432}
]