{"id":92570,"date":"2020-08-28T19:42:21","date_gmt":"2020-08-28T17:42:21","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/modelirovanie-otkazoustojchivyh-klasterov-na-baze-postgresql-i-pacemaker"},"modified":"2020-08-28T19:42:21","modified_gmt":"2020-08-28T17:42:21","slug":"modelirovanie-otkazoustojchivyh-klasterov-na-baze-postgresql-i-pacemaker","status":"publish","type":"post","link":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/modelirovanie-otkazoustojchivyh-klasterov-na-baze-postgresql-i-pacemaker","title":{"rendered":"Modeling fault-tolerant clusters based on PostgreSQL and Pacemaker","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<h1 id=\"vvedenie\">Introduction<\/h1>\n<p><\/p>\n<p>Some time ago, I was tasked with developing a fault-tolerant cluster for <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\">PostgreSQL<\/a><\/noindex>, operating across multiple data centers connected by fiber optics within a single city, and able to withstand the failure (for example, power outage) of a single data center. For the software responsible for fault tolerance, I chose <noindex><a rel=\"nofollow\" href=\"https:\/\/clusterlabs.org\">Pacemaker<\/a><\/noindex>, because it is the official solution from RedHat for creating fault-tolerant clusters. It is advantageous because RedHat provides support for it, and it is a universal (modular) solution. With it, resilience can be ensured not only for PostgreSQL but also for other services, either using standard modules or creating them tailored to specific needs.<\/p>\n<p><\/p>\n<p>A reasonable question arose regarding this solution: how resilient will the fault-tolerant cluster be? To investigate this, I developed a test setup that simulates various failures on the cluster nodes, waits for recovery, restores the failed node, and continues testing in a loop. Initially, this project was called hapgsql, but over time, I got bored with a name that had only one vowel. Therefore, I started naming the fault-tolerant databases (and the floating IPs pointing to them) <strong>krogan<\/strong> (a character from a video game whose vital organs are all replicated), while the nodes, clusters, and the project itself are called <strong>tuchanka<\/strong> (the planet where krogan live).<\/p>\n<p><\/p>\n<p>Currently, management has allowed <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/domclick\/tuchanka\">to open the project to the open-source community under the MIT license<\/a><\/noindex>. A README will soon be translated into English (since it is expected that the main users will be developers of Pacemaker and PostgreSQL), and I decided to present the old Russian version of the README (partially) in the form of this article.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modeling fault-tolerant clusters based on PostgreSQL and Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/7ebb04b3e56337060e981da319192a28.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>The clusters are deployed on virtual machines <noindex><a rel=\"nofollow\" href=\"https:\/\/www.virtualbox.org\">VirtualBox<\/a><\/noindex>. A total of 12 virtual machines will be deployed (a total of 36GiB), which will form 4 fault-tolerant clusters (different configurations). The first two clusters consist of two PostgreSQL servers located in different data centers, and a common server <em>witness<\/em> c <strong>quorum device<\/strong> (hosted on a cheap virtual machine in a third data center), which resolves uncertainty <strong>50%\/50%<\/strong>, casting its vote for one side. The third cluster spans three data centers: one master, two slaves, without <strong>quorum device<\/strong>The fourth cluster consists of four PostgreSQL servers, two for each data center: one master and the other replicas, and it also uses <em>witness<\/em> c <strong>quorum device<\/strong>The fourth can withstand the failure of two servers or one data center. This solution can be scaled up to accommodate more replicas if necessary.<\/p>\n<p><\/p>\n<p>Time Synchronization Service <noindex><a rel=\"nofollow\" href=\"https:\/\/www.ntp.org\">ntpd<\/a><\/noindex> is also reconfigured for fault tolerance, but it uses the method of <code>ntpd<\/code> (<em>orphan mode<\/em>). The main server <em>witness<\/em> acts as the central NTP server, distributing its time to all clusters, thereby synchronizing all servers with each other. If <em>witness<\/em> fails or becomes isolated, then one of the servers in the cluster (within the cluster) will start to distribute its time. A supporting caching <strong>HTTP proxy<\/strong> is also set up on <em>witness<\/em>, allowing the other virtual machines to access Yum repositories. In reality, services such as time synchronization and proxy will likely be hosted on dedicated servers, while in this setup they are placed on <em>witness<\/em> only for the sake of saving on the number of virtual machines and space.<\/p>\n<p><\/p>\n<h1 id=\"versii\">Versions<\/h1>\n<p><\/p>\n<p>v0. It works with CentOS 7 and PostgreSQL 11 on VirtualBox 6.1.<\/p>\n<p><\/p>\n<h1 id=\"struktura-klasterov\">Cluster Structure<\/h1>\n<p><\/p>\n<p>All clusters are designed to be hosted across multiple data centers, unified into one flat network, and must withstand the failure or network isolation of one data center. Therefore, <strong>is not possible<\/strong> use to protect against <strong>split-brain<\/strong> the standard technology of Pacemaker, which is called <em>STONITH<\/em> (Shoot The Other Node In The Head) or <em>fencing<\/em>. Its essence: if nodes in the cluster begin to suspect that something is wrong with a certain node, which is unresponsive or behaving incorrectly, they forcibly disable it via \"external\" devices, such as an IPMI management card or UPS. However, this will only work in cases where, during a single server failure, the IPMI or UPS continues to operate. Here, protection against a much more catastrophic failure is planned, where an entire data center fails (for example, loses power). In such a failure, all <em>stonith<\/em>-devices (IPMI, UPS, etc.) will also not work.<\/p>\n<p><\/p>\n<p>Instead, the system is based on the idea of quorum. All nodes have a vote, and only those that can see more than half of all nodes can operate. This number of \"half+1\" is called <strong>quorum<\/strong>. If a quorum is not reached, the node decides that it is in network isolation and must disable its resources, i.e. it is a kind of <strong>protection against split-brain<\/strong>If the software that controls such behavior is not functioning, a watchdog, for example based on IPMI, should take action.<\/p>\n<p><\/p>\n<p>If the number of nodes is even (a cluster in two data centers), a so-called uncertainty may arise. <strong>50%\/50%<\/strong> (<em>fifty-fifty<\/em>), when network isolation splits the cluster exactly in half. Therefore, for an even number of nodes, a <strong>quorum device<\/strong> \u2014 lightweight daemon that can run on the cheapest virtual machine in the third data center. It casts its vote for one of the segments (that it can see), thereby resolving the 50%\/50% uncertainty. The server on which the quorum device will be running, I named <em>witness<\/em> (terminology from repmgr, which I liked).<\/p>\n<p><\/p>\n<p>Resources can move from one place to another, for example, from defective servers to functioning ones, or by the command of system administrators. To inform clients where their needed resources are located (where to connect?), floating <em>IP addresses<\/em> (<strong>float IP<\/strong>). These are IPs that Pacemaker can move across nodes (everything is in a flat network). Each of them symbolizes a resource (service) and will be where clients need to connect to access this service (in our case, the database).<\/p>\n<p><\/p>\n<h2 id=\"tuchanka1-shema-s-uplotneniem\">Tuchanka1 (squeeze scheme)<\/h2>\n<p><\/p>\n<h3 id=\"struktura\">Structure<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modeling fault-tolerant clusters based on PostgreSQL and Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/5651238e36f4af1c32f117191cf30261.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>The idea was that we have many small databases with low load, for which it is not cost-effective to maintain a dedicated slave server in hot standby mode for read-only transactions (there's no need for such resource waste).<\/p>\n<p><\/p>\n<p>In each data center, there is one server. Each server hosts two instances of PostgreSQL (in PostgreSQL terminology, they are called clusters, but to avoid confusion, I will refer to them as instances (similarly to other databases), and will only call the groups Pacemaker clusters). One instance operates in master mode, and only it provides services (only it has the float IP). The second instance functions as a slave for the second data center and will only provide services if its master fails. Since most of the time only one instance (the master) will provide services (execute queries), all server resources are optimized for the master (memory is allocated for shared_buffers cache, etc.), while still ensuring that there are enough resources for the second instance (even for less optimal operation via the file system cache) in case one of the data centers fails. The slave does not provide services (does not perform read-only queries) during normal cluster operation to avoid resource contention with the master on the same machine.<\/p>\n<p><\/p>\n<p>In the case of two nodes, fault tolerance is only possible with asynchronous replication, as synchronous failure of the slave will result in the master stopping.<\/p>\n<p><\/p>\n<h3 id=\"otkaz-witness\">Witness failure<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modeling fault-tolerant clusters based on PostgreSQL and Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/3c046d13c0c6839de297827ca3a8928b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Witness failure (<em>quorum device<\/em>) I will only consider this for the Tuchanka1 cluster; the same situation applies to all others. In the event of a witness failure in the cluster structure, there will be no changes, everything will continue to operate as it did before. However, the quorum will become 2 out of 3, meaning any subsequent failure will be fatal for the cluster. It will still need to be urgently fixed.<\/p>\n<p><\/p>\n<h3 id=\"otkaz-tuchanka1\">Tuchanka1 failure<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modeling fault-tolerant clusters based on PostgreSQL and Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/112957293bd682428115e4e93c9f1a96.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Failure of one of the data centers for Tuchanka1. In this case, <em>witness<\/em> it gives its vote to the second node in the second data center. There, the former slave becomes the master, resulting in both masters operating on one server, and both of their float IPs point to them.<\/p>\n<p><\/p>\n<h2 id=\"tuchanka2-klassicheskaya\">Tuchanka2 (classical)<\/h2>\n<p><\/p>\n<h3 id=\"struktura-1\">Structure<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modeling fault-tolerant clusters based on PostgreSQL and Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/c3af368f823fbd580b4ebb14cc87c750.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>The classical configuration consists of two nodes. One operates as the master, the other as the slave. Both can execute queries (the slave is only read-only), so both are assigned float IPs: krogan2 \u2014 for the master, krogan2s1 \u2014 for the slave. There will be fault tolerance for both the master and the slave.<\/p>\n<p><\/p>\n<p>In the case of two nodes, fault tolerance is only possible with asynchronous replication because the synchronous failure of the slave will lead to the stoppage of the master.<\/p>\n<p><\/p>\n<h3 id=\"otkaz-tuchanka2\">Tuchanka2 failure<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modeling fault-tolerant clusters based on PostgreSQL and Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/79bfcaf88c96d8ee16767dcef53741c1.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>In the event of a failure of one of the data centers <em>witness<\/em> votes for the second. A master will be set up at the only functioning data center, and both float IPs\u2014master and slave\u2014will point to it. Naturally, the instance must be configured in such a way that it has sufficient resources (connection limits, etc.) to simultaneously handle all connections and requests from both the master and slave float IPs. Thus, under normal operation, it should have a substantial buffer in the limits.<\/p>\n<p><\/p>\n<h2 id=\"tuchanka4-mnogo-rabov\">Tuchanka4 (many slaves)<\/h2>\n<p><\/p>\n<h3 id=\"struktura-2\">Structure<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modeling fault-tolerant clusters based on PostgreSQL and Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/17819fd97847f0573d429e422d799bc1.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>It's a different extreme. There are databases with a high volume of read-only requests (a typical case of a high-load website). Tuchanka4 is a situation where there can be three or more slaves processing such requests, but still not too many. With a very large number of slaves, a hierarchical replication system will need to be devised. In the minimal case (as shown in the image), each of the two data centers has two servers, each with an instance of PostgreSQL.<\/p>\n<p><\/p>\n<p>Another feature of this scheme is that it\u2019s possible to organize synchronous replication here. It is configured to replicate to another data center whenever possible, rather than to a replica in the same data center as the master. A float IP points to both the master and each slave. Ideally, requests should be load-balanced among the slaves using some method <em>sql proxy<\/em>, for example, on the client side. Different types of clients may require different types <em>sql proxy<\/em>, and only client developers know what each one needs. This functionality can be implemented as an external daemon, a client library (connection pool), etc. All of this goes beyond the scope of a fault-tolerant database cluster (fault tolerance <em>SQL proxy<\/em> can be implemented independently, along with client fault tolerance).<\/p>\n<p><\/p>\n<h3 id=\"otkaz-tuchanka4\">Failure of Tuchanka4<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modeling fault-tolerant clusters based on PostgreSQL and Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/e005ae90ffd63abdb272012b94735618.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>In the event of a failure of one data center (i.e., two servers), the witness votes for the second. As a result, two servers operate in the second data center: one is the master with the master float IP (for handling read-write requests); and the second server has a slave with synchronous replication, which is pointed to by one of the slave float IPs (for read-only requests).<\/p>\n<p><\/p>\n<p>The first thing to note is that not all slave float IPs will be operational, but only one. For correct operation with it, it will be necessary for <em>sql proxy<\/em> redirected all requests to the only remaining float IP; if not, <em>sql proxy<\/em> then you can list all float IP slaves in the URL for connection, separated by commas. In that case, the connection will be to the first working IP, as implemented in the automatic testing system. However, this may not work in other libraries, such as JDBC, and it is necessary <em>libpq<\/em> for the connection to the first working IP, as designed in the automatic testing system. It may not function the same way in other libraries, such as JDBC, and additional <em>sql proxy<\/em>. This is implemented because the float IP for the slaves is restricted from running on the same server simultaneously, ensuring they are evenly distributed across the slave servers when multiple are in operation.<\/p>\n<p><\/p>\n<p>Second: even in the event of a data center failure, synchronous replication will be maintained. Even if a secondary failure occurs, meaning one of the two servers in the remaining data center fails, the cluster, although it will stop providing services, will still retain information about all committed transactions for which it has acknowledged a commit (there will be no data loss during the secondary failure).<\/p>\n<p><\/p>\n<h2 id=\"tuchanka3-3-data-centra\">Tuchanka3 (3 data centers)<\/h2>\n<p><\/p>\n<h3 id=\"struktura-3\">Structure<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modeling fault-tolerant clusters based on PostgreSQL and Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/e11f9884b92fe20a63b5080ae8c7f82b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>This cluster is for situations where there are three fully operational data centers, each with a fully functioning database server. In this case, <em>quorum device<\/em> is not required. One data center operates the master, while the other two operate the slaves. Replication is synchronous, of the ANY type (slave1, slave2), meaning the client will receive a commit acknowledgment as soon as any of the slaves responds that it has received the commit. The resources are pointed out by one float IP for the master and two for the slaves. Unlike Tuchanka4, all three float IPs are fault-tolerant. For load balancing read-only SQL queries, one can use <em>sql proxy<\/em> (with separate fault tolerance), or assign one slave float IP to half of the clients and the other half to the second.<\/p>\n<p><\/p>\n<h3 id=\"otkaz-tuchanka3\">Failure of Tuchanka3<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modeling fault-tolerant clusters based on PostgreSQL and Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/1e61158be3c23742384d3621e8f7896b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>In the event of a failure of one of the data centers, two remain. One is running the master and the master\u2019s float IP, while the other is running a slave and both slave float IPs (the instance must have double the resource reserve to accept all connections from both slave float IPs). There is synchronous replication between the master and the slave. Additionally, the cluster will retain information about committed and confirmed transactions (there will be no data loss) in the event of the destruction of two data centers (if they are not destroyed simultaneously).<\/p>\n<p><\/p>\n<p><em>I decided not to include a detailed description of the file structure and deployment. Those who want to experiment can read all about it in README. I am only providing a description of the automated testing.<\/em><\/p>\n<p><\/p>\n<h1 id=\"sistema-avtomaticheskogo-testirovaniya\">Automated Testing System<\/h1>\n<p><\/p>\n<p>To test the fault tolerance of clusters with simulated various failures, an automated testing system has been created. It is launched via a script <code>test\/failure<\/code>. The script can accept as parameters the numbers of the clusters that you want to test. For example, this command:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">test\/failure 2 3<\/code><\/pre>\n<p><\/p>\n<p>will test only the second and third clusters. If no parameters are specified, all clusters will be tested. All clusters are tested in parallel, and the results are displayed in the tmux panel. Tmux uses a dedicated tmux server, so the script can be run from the default tmux, which results in nested tmux sessions. I recommend using a terminal in a large window with a small font. Before testing begins, all virtual machines are rolled back to a snapshot taken at the moment the script finishes. <code>setup<\/code>.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modeling fault-tolerant clusters based on PostgreSQL and Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/b546bab1ebbbe365991e1ff3d1667237.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>The terminal is divided into columns based on the number of tested clusters; by default (as shown in the screenshot), there are four. I will describe the contents of the columns using Tuchanka2 as an example. The panels in the screenshot are numbered:<\/p>\n<p><\/p>\n<ol>\n<li>Here, statistics for the tests are displayed. Columns:\n<ul>\n<li><strong>failure<\/strong> \u2014 the name of the test (function in the script) that simulates the failure.<\/li>\n<li><strong>reaction<\/strong> \u2014 the average time in seconds that the cluster took to restore its functionality. The measurement is taken from the start of the script that simulates the failure until the cluster restores its operational capability and can continue providing services. If the time is very short, for example, six seconds (this happens in clusters with multiple slaves such as Tuchanka3 and Tuchanka4), it means that the failure occurred on an asynchronous slave and did not affect the operational capacity; there were no changes in the state of the cluster.<\/li>\n<li><strong>deviation<\/strong> \u2014 indicates the range (accuracy) of the value <strong>reaction<\/strong> by the method of 'standard deviation.'<\/li>\n<li><strong>count<\/strong> \u2014 how many times this test was executed.<\/li>\n<\/ul>\n<\/li>\n<li>The brief log allows you to assess what the cluster is currently doing. The iteration number (test), timestamp, and operation name are displayed. An execution that takes too long (&gt; 5 minutes) indicates some issue.<\/li>\n<li><strong>heart<\/strong> (heart) \u2014 current time. For visual assessment of performance <em>master<\/em> its table continuously logs the current time using the master's float IP. If successful, the result is displayed in this panel.<\/li>\n<li><strong>beat<\/strong> (pulse) \u2014 the 'current time' that was previously recorded by the script <strong>heart<\/strong> in the master, is now read from <em>the slave<\/em> through its float IP. This allows for a visual assessment of the performance of the slave and replication. There are no slaves with float IP in Tuchanka1 (no slaves providing services), but there are two instances (DB), so it will show not <strong>beat<\/strong>, and <strong>heart<\/strong> the second instance.<\/li>\n<li>Cluster state monitoring using the utility <code>pcs mon<\/code>. It shows the structure, resource distribution across nodes, and other useful information.<\/li>\n<li>Here is the system monitoring output from each virtual machine in the cluster. There can be more such panels \u2014 as many as the virtual machines in the cluster. Two graphs <em>CPU Load<\/em> (with two processors in each VM), the name of the virtual machine, <em>System Load<\/em> (named Load Average, because it is averaged over 5, 10, and 15 minutes), process data, and memory distribution.<\/li>\n<li>Script tracing for testing. In case of failure \u2014 sudden interruption of work or infinite waiting cycle \u2014 the reason for such behavior can be seen here.<\/li>\n<\/ol>\n<p><\/p>\n<p>Testing is conducted in two stages. First, the script goes through all variants of tests, randomly selecting a virtual machine to which this test is applied. Then an infinite testing loop is executed, with virtual machines and failures chosen randomly each time. A sudden termination of the testing script (bottom panel) or an infinite wait for something (&gt; 5 minutes of operation time is visible in the trace) indicates that one of the tests on this cluster has failed.<\/p>\n<p><\/p>\n<p>Each test consists of the following operations:<\/p>\n<p><\/p>\n<ol>\n<li>Launching a function emulating a failure.<\/li>\n<li><strong>Ready?<\/strong> \u2014 waiting for restoration of cluster functionality (when all services are restored).<\/li>\n<li>The time waiting for the restoration of the cluster is shown (<em>reaction<\/em>).<\/li>\n<li><strong>Fix<\/strong> \u2014 the cluster is being 'fixed'. After this, it should return to fully functional condition and readiness for the next failure.<\/li>\n<\/ol>\n<p><\/p>\n<p>Here is a list of tests with descriptions of what they do:<\/p>\n<p><\/p>\n<ul>\n<li><strong>ForkBomb<\/strong>: creates an &quot;Out of memory&quot; error with a fork bomb.<\/li>\n<li><strong>OutOfSpace<\/strong>: fills the hard drive. However, the test is rather symbolic; with the minimal load generated during testing, PostgreSQL typically does not fail when the hard drive is full.<\/li>\n<li><strong>Postgres-KILL<\/strong>: kills PostgreSQL with the command <code>killall -KILL postgres<\/code>.<\/li>\n<li><strong>Postgres-STOP<\/strong>: suspends PostgreSQL with the command <code>killall -STOP postgres<\/code>.<\/li>\n<li><strong>PowerOff<\/strong>: \"powers off\" the virtual machine with the command <code>VBoxManage controlvm &quot;virtual machine&quot; poweroff<\/code>.<\/li>\n<li><strong>Reset<\/strong>: resets the virtual machine with the command <code>VBoxManage controlvm &quot;virtual machine&quot; reset<\/code>.<\/li>\n<li><strong>SBD-STOP<\/strong>: suspends the SBD daemon with the command <code>killall -STOP sbd<\/code>.<\/li>\n<li><strong>ShutDown<\/strong>: sends a command via SSH to the virtual machine <code>systemctl poweroff<\/code>, and the system shuts down correctly.<\/li>\n<li><strong>UnLink<\/strong>: network isolation, command <code>VBoxManage controlvm &quot;virtual machine&quot; setlinkstate1 off<\/code>.<\/li>\n<\/ul>\n<p><\/p>\n<p>End testing either using the standard tmux command &quot;kill-window&quot; <strong>Ctrl-b &amp;<\/strong>, or the command &quot;detach-client&quot; <strong>Ctrl-b d<\/strong>: at this point, the testing ends, tmux closes, and the virtual machines are powered off.<\/p>\n<p><\/p>\n<h1 id=\"vyyavlennye-pri-testirovanii-problemy\">Identified issues during testing<\/h1>\n<p><\/p>\n<ul>\n<li>\n<p>Currently, you have to choose either sound or suspend\/resume. We are waiting for the author of the bce module to finalize the functionality. <em>the watchdog daemon sbd<\/em> manages the stopping of monitored daemons but not their hanging. As a result, faults leading to hanging are not handled correctly, <em>Corosync<\/em> and <em>Pacemaker<\/em>, but do not suspend <em>sbd<\/em>. For verification <em>Corosync<\/em> already have <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/ClusterLabs\/sbd\/pull\/83\"><strong>PR#83<\/strong> (on GitHub under <em>sbd<\/em>)<\/a><\/noindex>, accepted into the branch <em>master<\/em>. They promised (in PR#83) that something similar would be done for Pacemaker, I hope it will be ready by <em>RedHat 8<\/em> . However, such \"malfunctions\" are theoretical and can be easily simulated artificially, for example, <code>killall -STOP corosync<\/code>, but are never encountered in real life.<\/p>\n<p>\n<\/li>\n<li>\n<p>The <em>Pacemaker<\/em> in the version for <em>CentOS 7<\/em> the sync_timeout <em>is set incorrectly, resulting in<\/em> at <em>quorum device<\/em>when one node fails, the second node reboots with some probability, <noindex><a rel=\"nofollow\" href=\"https:\/\/lists.clusterlabs.org\/pipermail\/users\/2019-August\/026145.html\">where the master was supposed to move. This was fixed by increasing<\/a><\/noindex>during deployment (in the script <em>is set incorrectly, resulting in<\/em> at <em>quorum device<\/em> setup\/setup1 <code>). This fix was not accepted by the developers,<\/code>instead, they promised to redesign the infrastructure in such a way (at some uncertain future point) that this timeout would be calculated automatically. <em>Pacemaker<\/em>If during the database configuration it is specified that in<\/p>\n<p>\n<\/li>\n<li>\n<p>LC_MESSAGES <code>(text messages) Unicode can be used, for example,<\/code> ru_RU.UTF-8 <code>, then when launched<\/code>in an environment where the locale is not UTF-8, say, in a blank environment (here <em>postgres<\/em> pacemaker <em>pgsqlms<\/em>+<em>(paf) starts<\/em>instead of UTF-8 letters, question marks will appear in the log. <em>postgres<\/em>), then <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/message-id\/13FE0F7C-5140-499C-8C2E-0BE64BC3A48B%40ya.ru\">The PostgreSQL developers did not come to a consensus on what to do in this case. It is worked around by setting<\/a><\/noindex>LC_MESSAGES=en_US.UTF-8 <code>LC_MESSAGES=en_US.UTF-8<\/code> when configuring (creating) a DB instance.<\/p>\n<p>\n<\/li>\n<li>\n<p>If wal_receiver_timeout is set (default is 60s), then when testing PostgreSQL-STOP on the master in the tuchanka3 and tuchanka4 clusters <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/message-id\/60590EC6-4062-4F25-A49C-3948ED2A7D47%40ya.ru\">there is no reconnection of replication to the new master.<\/a><\/noindex>. The replication is synchronous there, so not only the worker stops, but also the new master. This can be bypassed by setting wal_receiver_timeout=0 when configuring PostgreSQL.<\/p>\n<p>\n<\/li>\n<li>\n<p>Occasionally, I observed replication freezing in PostgreSQL during the ForkBomb test (memory overflow). <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/message-id\/60590EC6-4062-4F25-A49C-3948ED2A7D47%40ya.ru\">After ForkBomb, sometimes the workers may not reconnect to the new master.<\/a><\/noindex>. I have only encountered this in the tuchanka3 and tuchanka4 clusters, where due to synchronous replication, the master hung. The issue resolved itself after a while (about two hours). Further investigation is needed to fix this. The symptoms resemble a previous bug caused by a different reason but with similar consequences.<\/p>\n<p>\n<\/li>\n<\/ul>\n<p><\/p>\n<p>The krogan image is taken from <noindex><a rel=\"nofollow\" href=\"http:\/\/fav.me\/d8fo42n\">Deviant Art<\/a><\/noindex> with the author's permission:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modeling fault-tolerant clusters based on PostgreSQL and Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/ded1ead387814d97d84d0fb89e025386.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Source: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/domclick\/blog\/516538\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 \u043f\u0435\u0440\u0435\u0434\u043e \u043c\u043d\u043e\u0439 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0443 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u0434\u043b\u044f PostgreSQL, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0434\u0430\u0442\u0430-\u0446\u0435\u043d\u0442\u0440\u0430\u0445, \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u043d\u044b\u0445 \u043e\u043f\u0442\u043e\u0432\u043e\u043b\u043e\u043a\u043d\u043e\u043c \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0433\u043e \u0433\u043e\u0440\u043e\u0434\u0430, \u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u044b\u0439 \u0432\u044b\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043e\u0442\u043a\u0430\u0437 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e\u0431\u0435\u0441\u0442\u043e\u0447\u0438\u0432\u0430\u043d\u0438\u0435) \u043e\u0434\u043d\u043e\u0433\u043e \u0434\u0430\u0442\u0430-\u0446\u0435\u043d\u0442\u0440\u0430. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u043e\u0444\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c, \u0432\u044b\u0431\u0440\u0430\u043b Pacemaker, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u044d\u0442\u043e \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043e\u0442 RedHat \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0445 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u043e\u0432. \u041e\u043d\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u0442\u0435\u043c, \u0447\u0442\u043e [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":92571,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-92570","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 \u043f\u0435\u0440\u0435\u0434\u043e \u043c\u043d\u043e\u0439 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0443 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u0434\u043b\u044f PostgreSQL.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/modelirovanie-otkazoustojchivyh-klasterov-na-baze-postgresql-i-pacemaker\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0445 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u043e\u0432 \u043d\u0430 \u0431\u0430\u0437\u0435 PostgreSQL \u0438 Pacemaker | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 \u043f\u0435\u0440\u0435\u0434\u043e \u043c\u043d\u043e\u0439 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0443 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u0434\u043b\u044f PostgreSQL.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/modelirovanie-otkazoustojchivyh-klasterov-na-baze-postgresql-i-pacemaker\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-08-28T17:42:21+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-08-28T17:42:21+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Modeling Fault-Tolerant Clusters Based on PostgreSQL and Pacemaker | ProHoster","description":"Introduction Some time ago, I was tasked with developing a fault-tolerant cluster for PostgreSQL.","canonical_url":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/modelirovanie-otkazoustojchivyh-klasterov-na-baze-postgresql-i-pacemaker","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"en_US","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0445 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u043e\u0432 \u043d\u0430 \u0431\u0430\u0437\u0435 PostgreSQL \u0438 Pacemaker | ProHoster","og:description":"\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 \u043f\u0435\u0440\u0435\u0434\u043e \u043c\u043d\u043e\u0439 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0443 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u0434\u043b\u044f PostgreSQL.","og:url":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/modelirovanie-otkazoustojchivyh-klasterov-na-baze-postgresql-i-pacemaker","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-08-28T17:42:21+00:00","article:modified_time":"2020-08-28T17:42:21+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"92570","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 12:06:03","updated":"2022-09-29 15:28:29","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts\/92570","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/comments?post=92570"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts\/92570\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/media\/92571"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/media?parent=92570"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/categories?post=92570"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/tags?post=92570"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}