This site best when viewed with a modern standards-compliant browser. We recommend Firefox Get Firefox!.

Linux-HA project logo
Providing Open Source High-Availability Software for Linux and other OSes since 1999.

USA Flag UK Flag

Japanese Flag

Homepage

About Us

Contact Us

Legal Info

How To Contribute

Security Issues

7th - 10th September 2009 Linux-Kongress in Hamburg will have several sessions on Linux-HA - see you there!

18 August 2008 Heartbeat release 2.1.4 is now out Download it

11 October 2007 NEW educational HA/DR Blog hosted by Alan Robertson

9 April 2007 Check out the Cool Heartbeat Screencasts: Installation, Intro to the GUI Part of the Heartbeat Education project

Last site update:
2008-08-29 19:08:44

Contents

  1. Frequently Asked Questions for Heartbeat Version 2
    1. Why does crmadmin think my resource is not active?
    2. How Do I Write an OCF Compliant Resource Agent?
    3. Is my Init Script Compatible with Heartbeat?
    4. How do I monitor a resource for failure?
    5. What happens when monitor detects the resource down?
    6. Can I load a new cib.xml config in Heartbeat without restarting Heartbeat?
    7. Is it a good idea to keep the cib.xml in sync with the other nodes?
    8. What's the difference between all those timers/timeouts?
    9. How do I know Heartbeat is installed correctly?
    10. Why doesn't hb_standby do work in version 2?
    11. How do I replace a cluster node?
    12. See Also

Other FAQ entries included at the end of this page:

  1. ja/v2/faq/forced failover ja
  2. ja/v2/faq/manual recovery ja
  3. ja/v2/faq/pingd ja
  4. ja/v2/faq/resource too active ja
  5. ja/v2/faq/stop resource ja
  6. ja/v2/faq/time based failback ja
  7. v2/faq/cib changes detected
  8. v2/faq/forced failover
  9. v2/faq/manual recovery
  10. v2/faq/pingd
  11. v2/faq/resource too active
  12. v2/faq/stop resource
  13. v2/faq/time based failback

Frequently Asked Questions for Heartbeat Version 2

Why does crmadmin think my resource is not active?

Chances are you are trying to check a resource that is part of a group.

Try prepending the id of the group to the resource's name. Eg. crmadmin -W group_id:rsc_id

Version 2.0.3 allows you to use the short name (provided the short_resource_names option is set).

How Do I Write an OCF Compliant Resource Agent?

The OCF RA spec can be found here:
http://www.opencf.org/cgi-bin/viewcvs.cgi/specs/ra/resource-agent-api.txt?rev=HEAD

Is my Init Script Compatible with Heartbeat?

Init scripts are handled as LSBResourceAgents. Problems with them are quite common and the LSBResourceAgent page contains a series of steps to help you determine if the script is usable or not.

How do I monitor a resource for failure?

One of the most requested Heartbeat features was the ability for it to detect when a resource failed (not just the whole node).

To support this, the CRM also knows about monitor actions.

If you wish Heartbeat to make sure the resource is running, then you must specify one or more monitor actions in the operations section of the resource.

Each monitor action must specify an interval which tells Heartbeat how often it should check the resource's status.

To find out more, refer to section two of ClusterInformationBase/Actions and the section on actions in the annotated DTD

What happens when monitor detects the resource down?

The node will try to restart the resource, but if this fails, it will fail over to an other node.

A feature that allows failover after N failures in a given period of time is planned.

Can I load a new cib.xml config in Heartbeat without restarting Heartbeat?

Indeed you can. You will need the replace option of the cibadmin tool.

Is it a good idea to keep the cib.xml in sync with the other nodes?

Absolutely. However the ClusterInformationBase is supposed to do this automatically. If you find a situation where the contents on two active nodes is NOT in sync, please file a bug immediately.

What's the difference between all those timers/timeouts?

  • In the ha.cf:

    • deadtime: time before a node is defined dead if it hasn't got a keepalive in that time
    • deadping: the same as deadtime only in this case it is a ping node instead of a cluster node

    • conn_logd_time: time it takes for Heartbeat to reconnect to the logging deamon if this connection is broken
    • initdead: time that it takes to declare a cluster node dead when Heartbeat is first started
    • warntime: specifies how quickly Heartbeat should issue a "late heartbeat" warning
  • In the cib.xml:

    • transition_timeout: How long to wait before timing out the current transition and trying again. This happens either when an action fails or no other timeout is specified for an action.
    • timeout: in start, stop and monitor actions, the maximum period of time before considering the action failed

How do I know Heartbeat is installed correctly?

You can check your Heartbeat installation by running /usr/lib/heartbeat/BasicSanityCheck

Why doesn't hb_standby do work in version 2?

In VersionTwo you'll need to use crm_standby. See v2/AdminTools for more help on the available commands.

How Do I Force a Resource to be Migrated After a Failure?

In Versions prior to 2.0.5 there is no way to do this.

Subsequent versions can use the resource-failure-stickiness property of a resource (or the global default: default-resource-failure-stickiness) to control when failover happens.

Example

In a cluster where:

  • default-resource-failure-stickiness is -100

  • default-resource-stickiness is 500

  • Resource my_rsc prefers to run on nodeA with score 1500

  • Resource my_rsc prefers to run on nodeB with score 1000

my_rsc can fail up to ten times on nodeA before being moved to nodeB.

(nodeA score - nodeB score + stickiness) / abs(failure stickiness)

==> (1500 - 1000 + 500) / abs(-100)

==> 1000 / 100

==> Answer: 10

However if default-resource-failure-stickiness was set to -1001 or less, it would be moved immediately.

(nodeA score - nodeB score + stickiness) / abs(failure stickiness)

==> (1500 - 1000 + 500) / abs(-1001)

==> 1000 / 1001

==> Answer: 0.999

NOTE: Failure stickiness should be a negative value.
NOTE: The rules for +/-INFINITY apply...

 INFINITY +/- -INFINITY : -INFINITY
 INFINITY +/-  int      :  INFINITY
-INFINITY +/-  int      : -INFINITY

Multiple Failures

If the combined score for my_rsc on a node is less than zero, it will never be able to run there again until the failure count is reset.

The current failure count (for a given resource and node) is multiplied by the resource's failure stickiness to produce a failover score. When the failover score exceeds the regular preference to a given node, the node will be excluded from running the resource again (until the failure count is reset).

In the first example above (where default-resource-failure_stickiness is -100) my_rsc can fail up to 15 times on nodeA before Heartbeat will no longer consider running it there. Likewise it can fail up to 10 times on nodeB before that node will no longer be consider either.

In the second example (where default-resource-failure-stickiness is less than -500), these values drop to 3 and 2 failures respectively.

Resetting Failure Counts

To reset the failure count for my_rsc on nodeA, the following command can be used:

  • crm_failcount -D -U nodeA -r my_rsc

To query the current failure count, use:

  • crm_failcount -G -U nodeA -r my_rsc

Why the Failure Count is not Automatically Reset When a Resource is Moved

The failure count is not automatically reset when a resource is moved to prevent the resource from bouncing between two or more "bad" nodes.

How this works out with groups

When you use groups or other things with mandatory colocation constraints, it gets more complicated. If you take everything which you force to be colocated on the same machine, then all those things will be treated just as though they were in a group together. So, keep that in mind in the explanation below.

For a group with n resources, the resource-stickiness of the group of n resources is the sum of all the stickinesses in the group. Unless you've overridden the default for the resources in the group, that would be n times the default-resource-stickiness, and it is the stickiness of the group as a whole which is used, rather than the stickiness of any member of the group. The resource-failure-stickiness value for a group is computed in a similar way.

In addition, if you want to give a different resource-stickiness or resource-failure-stickiness to every member in the group, you can give this attribute to the group itself. However, it will effectively be multiplied by n in the process of summing up all the stickiness values of the group members, because this value is inherited by each primitive resource in the group, and then subjected to the summing process described above.

Things to keep in mind

  • You probably want every resource in the group to score the same, so that computing all these score differences for failures is simpler. A simple way to do this is to put your locational constraints on your groups rather than on individual resources in the group. Note that unlike the stickiness values, the scores for locational constraints on groups are not multiplied by n - so to make things balance out correctly, you may need to do this yourself when you create the corresponding CIB.

  • If you want to reset the failure counts so that things can fail back, you probably want to reset the failure counts of every resource in the group, since you don't know which one failed without searching the logs (see item below).

What you cannot do

You cannot force a group to fail over if any given resource in the group fails 'n' times. Failure counts for groups are cumulative. If you set it up so that 3 failures will cause a failover, then 3 failures of any resource in the group will cause a failover, not 3 for a particular resource. If you have a web server, an IP address and a mount point, then it will fail over with 3 web server failures, or one failure of each resource in the group.

A worked example involving a Group

Problem Definition

The outline of the requirements to be met are:

  • Two-node cluster
  • One group using pingd for pinging a gateway

  • Fail over the group on the third failure of any resource in the group
  • One node is preferred over the other
  • These location criteria are listed in order of decreasing importance:
    1. Don't run on a node which has failed 3 times without resetting failure counts (resource-failure-stickiness)

    2. Run on a node with ping access according to pingd

    3. Stay on the node you're on if it has ping access (resource-stickiness)

    4. Run the resource group on the designated (preferred) cluster node

Problem Solution

To be supplied

How do I Manually Recover a Resource?

Why is my Resource Listed as Unmanaged?

  • There are two common reasons for a reasons for the cluster to consider a resource unmanaged:
    • The resource is reported as active on more than one node
    • The resource failed to stop when the cluster asked it to and STONITH is not available

The authoritative source for information about what resources are active and what state they're in is the LRM. So while you could change the contents of the CIB directly, these changes are likely to be overwritten with data from the LRM at some point in the future.

Once you have manually stopped and otherwise cleaned up the resource, you should use the -C option for crm_resource to remove the resource from the LRM. More information on its usage is available with crm_resource --help. The general form is crm_resource -C -r my_resource_name. By default it will operate on all cluster nodes unless you specify -H some_host as well.

Since 2.0.5 the command will automatically instruct the cluster to refresh itself with the latest details from the LRM. Prior to that, users should "wait a bit" and run crm_resource -R.

Prior to 2.0.6 (which has not yet been released as of writing this) users had to be careful choosing the right value to use with -r. This affects resources in groups and is due to a bad choice earlier in the CRM's history and due to backwards compatibility we are stuck with it being the default.

The following command will list for you the internal names used by the cluster for its resources:
cibadmin -Ql -o status | grep "lrm_resource " | awk '{print $2}' | sort -u

Look for the one that matches your resource and use that value when calling crm_resource.

How Do I Monitor Connectivity in Version 2

pingd, An ipfail Replacement

pingd is a replacement for ipfail that like the rest of version 2 allows for connectivity (and resource placement based on relative connectivity) to work in clusters with any number of nodes.

The role of pingd is to detect changes to a node's connectivity and ensure that updates of this information to the CIB occur (at least effectively) simultaneously.

To locate your resources on the node(s) with the greatest connectivity, an admin needs to use the information placed in the CIB by pingd. This is achieved with the creation of resource location constraints that reference the attribute created by pingd. See "Using pingd Output in Location Constraints" below.

Configuration Methods

There are two options for configuring pingd

  1. The first is by adding a respawn directive to ha.cf eg:

    • respawn root /usr/lib/heartbeat/pingd -m 100 -d 5s
      See "pingd Usage Information" below for details on the meaning of the options passed to pingd.

  2. The other option is to create a clone using the pingd OCFResourceAgent. Since RA's are started as root, you need to add a line like "apiauth pingd uid=root" to your ha.cf or - even better - add the parameter user=hacluster to your RA configuration to use the implicit apiauth directive like the respawn method does. With version 2.0.6 you also have to add parameter pidfile which points to somewhere the chosen user has write permission (e.g. /tmp/pingd-default).

Both methods need the ping nodes listed in your ha.cf file. The host_list parameter of the RA can only use a subset of those, not some other hosts.

Both methods also require the addition of one-or-more colocation constraints to the CIB. See "Using pingd Output in Location Constraints" below.

The advantage of using the resource agent is that you can:

  • limit the connectivity information to nodes
    • with particular properties (names, ids, node attributes)
    • running a particular resource
  • dynamically alter any of the input or output options including
    • the list of ping nodes being monitored
    • the attribute name
    • the multiplier
    • the dampening delay

An equivalent resource for the respawn directive above would be:

<clone id="pingd-clone">
  <meta_attributes id="pingd-clone-ma">
    <attributes>
      <nvpair id="pingd-clone-1" name="globally_unique" value="false"/>
    </attributes>
  </meta_attributes>
  <primitive id="pingd-child" provider="heartbeat" class="ocf" type="pingd">
    <operations>
      <op id="pingd-child-monitor" name="monitor" interval="20s" timeout="60s" prereq="nothing"/>
      <op id="pingd-child-start" name="start" prereq="nothing"/>
    </operations>
    <instance_attributes id="pingd_inst_attr">
      <attributes>
         <nvpair id="pingd-1" name="dampen" value="5s"/>
         <nvpair id="pingd-2" name="multiplier" value="100"/>
      </attributes>
    </instance_attributes>
  </primitive>
</clone>

NOTE: Changing the attribute's location in the CIB, while possible, is discouraged. This is because you may end up with multiple copies of the attribute for each node... causing the cluster to behave differently than expected.

pingd Usage Information

usage: pingd [-V?p:a:d:s:S:h:Dm:]
        --help (-?)                     This text
        --daemonize (-D)                Run in daemon mode
        --pid-file (-p) <filename>      File in which to store the process' PID
                                        * Default=/tmp/pingd.pid
        --attr-name (-a) <string>       Name of the node attribute to set
                                        * Default=pingd
        --attr-set (-s) <string>        Name of the set in which to set the attribute
                                        * Default=cib-bootstrap-options
        --attr-section (-S) <string>    Which part of the CIB to put the attribute in
                                        * Default=status
        --ping-host (-h) <single_host_name> Monitor a subset of the ping nodes listed in ha.cf
                                            (can be specified multiple times)
        --attr-dampen (-d) <integer>        How long to wait for no further changes to occur before
                                            updating the CIB with a changed attribute
        --value-multiplier (-m) <integer>   For every connected node, add <integer> to the value set in the CIB
                                            * Default=1

Using pingd Output in Location Constraints

Example pingd Configuration

  • respawn root /usr/lib/heartbeat/pingd -m 100 -d 5s -a default_ping_set

Example CIB Contents

Node

Connected Ping Nodes

default_ping_set Value

c001n01

5

500

c001n02

4

400

c001n03

5

500

  • c001n04

    N/A

    N/A

    c001n05

    0

    0

Example Constraint

<rsc_location id="my_resource_connected" rsc="my_resource">
    <rule id="my_resource_connected_rule" score_attribute="default_ping_set">
       <expression id="my_resource_connected_expr_defined" attribute="default_ping_set" operation="defined"/>
    </rule>
</rsc_location>

The above constraint:

  • requires a value to be set for default_ping_set (c001n04 is unaltered)

  • requires the value of default_ping_set to be greater than 100 (c001n05 is unaltered)

  • increases the preference for my_resource to run on c001n01 by 500

  • increases the preference for my_resource to run on c001n02 by 400

  • increases the preference for my_resource to run on c001n03 by 500

Node

Connected Ping Nodes

default_ping_set Value

Combined Score

c001n01

5

500

500

c001n02

4

400

400

c001n03

5

500

500

  • c001n04

    N/A

    N/A

    0

    c001n05

    0

    0

    0

If we also had the following constraint:

<rsc_location id="my_resource_preferred" rsc="my_resource">
    <rule id="my_resource_prefer_c001n01" score="100">
       <expression id="my_resource_prefer_c001n01_expr" attribute="#uname" operation="eq" value="c001n01"/>
    </rule>
    <rule id="my_resource_prefer_c001n02" score="200">
       <expression id="my_resource_prefer_c001n02_expr" attribute="#uname" operation="eq" value="c001n02"/>
    </rule>
    <rule id="my_resource_prefer_c001n03" score="300">
       <expression id="my_resource_prefer_c001n03_expr" attribute="#uname" operation="eq" value="c001n03"/>
    </rule>
    <rule id="my_resource_never" score="-INFINITY" boolean_op="or">
       <expression id="my_resource_never_c001n04_expr" attribute="#uname" operation="eq" value="c001n04"/>
       <expression id="my_resource_never_c001n05_expr" attribute="#uname" operation="eq" value="c001n05"/>
    </rule>
</rsc_location>

Then the updated scores for running the resource would be:

Node

Connected Ping Nodes

default_ping_set Value

Combined Score

c001n01

5

500

600

c001n02

4

400

600

c001n03

5

500

800

  • c001n04

    N/A

    N/A

    -INFINITY

    c001n05

    0

    0

    -INFINITY

At this point, if the resource was not running or v2/dtd1.0/annotated#default resource stickiness was set to zero, then the resource would be started on c001n03 with c001n01 and c001n02 equally preferred as a backup.

However if the resource was running on c001n02 and resource_stickiness was set to 1000, then the updated scores would be:

Node

Connected Ping Nodes

default_ping_set Value

Combined Score

c001n01

5

500

600

c001n02

4

400

1600

c001n03

5

500

800

  • c001n04

    N/A

    N/A

    -INFINITY

    c001n05

    0

    0

    -INFINITY

and the resource would be left running on c001n02.

Alternatively, if resource_stickiness was set to 100, then the scores would look like this:

Node

Connected Ping Nodes

default_ping_set Value

Combined Score

c001n01

5

500

600

c001n02

4

400

700

c001n03

5

500

800

  • c001n04

    N/A

    N/A

    -INFINITY

    c001n05

    0

    0

    -INFINITY

and the resource would be moved to c001n03.

This should also adequately demonstrate the importance of correctly setting:

  • pingd's --value-multiplier option

  • default_resource_stickiness / resource_stickiness

  • score in rsc_location constraints

Quickstart - Only Run my_resource on Nodes with Access to at Least One Ping Node

Add this to ha.cf

  • respawn root /usr/lib/heartbeat/pingd -m 100 -d 5s -a pingd

Add this constraint to the CIB:

It is sometimes desirable to shut a particular service down if ping connectivity is lost. This rule will prohibit the service from running anywhere that there is no ping connectivity to the outside world, and all nodes with some connectivity are treated as the same, regardless of how many ping nodes are accessible.

<rsc_location id="my_resource:connected" rsc="my_resource">
  <rule id="my_resource:connected:rule" score="-INFINITY" boolean_op="or">
    <expression id="my_resource:connected:expr:undefined"
      attribute="pingd" operation="not_defined"/>
    <expression id="my_resource:connected:expr:zero"
      attribute="pingd" operation="lte" value="0"/>
  </rule>
</rsc_location>

Of course, if you have configured the pingd daemon to set some attribute name besides its default (pingd), then you need to change the name of the attribute above from pingd to whatever name you have configured the pingd daemon to use.

Attention: Note that this will stop the resource everywhere if the pinged node(s) indeed go down or heartbeat loses connectivity to them (firewalls et cetera). Consider using the wiki:CIB/Idioms/PingdAttrAsScore instead, which instead expresses a positive preference for the node with the best connectivity.

The respawn rule for pingd from above can be used, or virtually any method of starting pingd with any non-zero --value-multiplier factor. If you have more than one ping node, you can run the resource, if not you can't. It's that simple.

Quickstart - Run my resource on the node with the best connectivity

This is probably one of the better ways to use pingd. In this method, the pingd attribute value becomes the score for the rule. So, the --value-multiplier you set will depend heavily on the scores you give other criteria. This rule will not stop a resource completely if all nodes lose connectivity to the outside world.

It is often desirable to allow the value of the attribute that pingd sets directly as a the score for a particular rule.

If you set the pingd scaling factor to 100, then having access to one node is worth 100, 2 nodes is worth 200, and so on.

This way, if all else is equal, the node with the highest ping connectivity will be selected. If two or more eligible nodes have the same score, then they will be given equal weight according to the rule below.

<rsc_location id="my_resource:connected" rsc="my_resource">
  <rule id="my_resource:connected:rule" score_attribute="pingd" >
    <expression id="my_resource:connected:expr:defined"
      attribute="pingd" operation="defined"/>
  </rule>
</rsc_location>

Of course, if you have configured the pingd daemon to set some attribute name besides its default (pingd), then you need to change the name of the score_attribute above from pingd to whatever attribute you have configured the pingd daemon to use.

Resource X is (potentially) active on 2 nodes.

Heartbeat will try and determine what resources are active on a machine when it starts. To do this, it sends what we call a probe which uses the monitor operation of your ResourceAgent.

There are two common reasons for seeing this message:

  1. Your resource really is active on more than one node
    • Check you are not starting it on boot
    • Did Heartbeat suffer an internal failure?

      If so, please check the ReportingProblems page and report it

  2. Your resource doesn't implement the monitor operation correctly
    • Make sure your ResourceAgent conforms to the OCF-spec

      • return 0 only for active resource instances
      • return 7 for inactive resource instances
      • return anything else for failed resource instances

How do I Make the Cluster Stop Resource X?

As of version 2.0.5 it is now possible to ask the cluster to stop a resource and leave it stopped.

To do this, you need to set an instance attribute called target_role for the resource.

To do this, your resource definition should look like something this:

 <resources>
   <group id="cds_grp">
     <primitive class="ocf" id="cds_res" provider="heartbeat" type="cds">
       <instance_attributes id="cds-defaults">
          <attributes>
             <nvpair id="cds-role" name="target_role" value="Stopped"/>
          </attributes>
       </instance_attributes>
     </primitive>
   </group>
 </resources>

Once you have done whatever you needed to do and are ready to start it again, the following command will tell the cluster to start it.

cibadmin -M -o resources -X '<nvpair id="cds-role" value="Started"/>'

To later cause the resource to be stopped again, you would run:

cibadmin -M -o resources -X '<nvpair id="cds-role" value="Stopped"/>'

Describe v2/faq/time based failback here.

How Do I Prevent a Resource from Failing Over During the Week but not on Weekends?

You need to use multiple instance_attributes sets with rules with date_expressions.

An example of an IP address that is allowed to be moved only on weekends is listed below.

<primitive id="my_ip" provider="heartbeat" class="OCF" type="IPaddr">
   <instance_attributes id="my_ip:weekend_override" score="100">
     <rule id="my_ip:failover" boolean_op="and">
       <date_expression id="my_ip:days" operation="date_spec">
         <date_spec id="my_ip:days" weekdays="6-7"/>
       </date_expression>
     </rule>
     <attributes>
       <nvpair id="sat-sun-sticky" name="resource_stickiness" value="0"/>
     </attributes>
   </instance_attributes>
   <instance_attributes id="my_ip" score="10">
      <attributes>
        <nvpair id="mon-fri-sticky" name="resource_stickiness" value="INFINITY"/>
      </attributes>
   </instance_attributes>
</primitive>

Note the use of score to determin the order in which the sets are processed in. Sets with a higher score will be processed before sets with lower scores.

To further restrict the failover to the hours of 2am to 5am on the weekend, you could construct something like the resource below:

<primitive id="my_ip" provider="heartbeat" class="OCF" type="IPaddr">
   <instance_attributes id="my_ip:weekend_override" score="100">
     <rule id="my_ip:failover" boolean_op="and">
       <date_expression id="my_ip:days" operation="date_spec">
         <date_spec id="my_ip:days" weekdays="6-7"/>
       </date_expression>
       <date_expression id="my_ip:times" operation="date_spec">
         <date_spec id="my_ip:times" hours="2-5"/>
       </date_expression>
     </rule>
     <attributes>
       <nvpair id="sat-sun-sticky" name="resource_stickiness" value="0"/>
     </attributes>
   </instance_attributes>
   <instance_attributes id="my_ip" score="10">
      <attributes>
        <nvpair id="mon-fri-sticky" name="resource_stickiness" value="INFINITY"/>
      </attributes>
   </instance_attributes>
</primitive>

How do I replace a cluster node?

Each cluster node has an UUID which is usually created and assigned to the node from heartbeat on at the first start of the cluster framework. If you start heartbeat on the replacement node (even if it has the same host name and IP address like the original node) it will have a different UUID than the orginal node. The result is the replacement node will not show up in your cluster. Some interesting facts:

  • each node has a text file showing the UUID of recognized cluster nodes in /var/lib/heartbeat/hostcache

  • the binary version of a node UUID (used by heartbeat) is stored in hb_uuid

  • don't edit those files manually - there are tools to handle those files: hb_addnode, hb_delnode, crm_uuid

  • delnodecache is used to remember the names of deleted machines which cannot automatically rejoin the cluster - this is to make the autojoin directive work the way we think it ought to.

As usual there are more ways to reach the goal:

  1. you have the copy of hb_uuid of the node which should be replaced

  2. you do not have the copy of hb_uuid but you have a heartbeat release which can create a binary UUID (crm_uuid -w) from the ASCII UUID

  3. you assign the replaced node a new UUID

Preconditions:

  • the old node was replaced with the new one (cabling etc.)
  • the replacement node has the same hostname
  • thew new node is configured to be ready to deploy hearteat (configuration files like /etc/ha.d/ha.cf etc. are in place)

  • the new node is powered on but heartbeat was not started yet (otherwise it would assign a new UUID to the new node which we try to avoid, and if autojoin is enabled, it would join the cluster with a new uuid, which would make a mess of things.)

Here are the steps replacing node2 of a cluster with 2 nodes (node1 and node2) for the different cases:

  • you have a copy of hb_uuid from the old node2

  • copy the file into /var/lib/heartbeat of the new node2

  • start heartbeat on node2 - finished

  • make sure heartbeat is started automatically after a node reboot
  • you do not have the copy of hb_uuid of node2 but you have a hearbeat release which can create a binary UUID (crm_uuid -w) from the ASCII UUID.

NOTE: heartbeat release 2.0.8 crm_uuid does not have the functionality creating the binary UUID (-w option). The following steps will work beginning with release 2.1.0.

  1. on node1 get the UUID of the orginal node2 in ASCII format (you can retrieve it from the CIB <nodes> section or from the file /var/lib/heartbeat/hostcache mentioned earlier). Here the <nodes> section of our example which tells us node2 had UUID a69b64a2-4de8-4d4a-b4ba-8107136eec4b.

   <nodes>
       <node id="a0e71041-8cbd-449a-a04b-0da3da3d82a6" uname="node1" type="normal">
         <instance_attributes id="nodes-a0e71041-8cbd-449a-a04b-0da3da3d82a6">
           <attributes>
             <nvpair id="standby-a0e71041-8cbd-449a-a04b-0da3da3d82a6" name="standby" value="off"/>
           </attributes>
         </instance_attributes>
       </node>
       <node id="a69b64a2-4de8-4d4a-b4ba-8107136eec4b" uname="node2" type="normal">
         <instance_attributes id="nodes-a69b64a2-4de8-4d4a-b4ba-8107136eec4b">
           <attributes>
             <nvpair id="standby-a69b64a2-4de8-4d4a-b4ba-8107136eec4b" name="standby" value="on"/>
           </attributes>
         </instance_attributes>
       </node>
   <nodes/>
  1. on node2 use crm_uuid -w to create the binary UUID of node2.

ATTENTION: make sure you do this on the right node because it will overwrite hb_uuid on the node where you call it

node2:/tmp# crm_uuid -w a69b64a2-4de8-4d4a-b4ba-8107136eec4b
  1. restart heartbeat on node2 - finished

  2. make sure heartbeat is automatically started after a system reboot

In case heartbeat was started on the replacement node2 before you could do the procedure explained above, heartbeat assigned a new UUID to node2. node2 will be recognized as different from the original node2. It will not be integrated into the cluster, even if hostname and IP address are the same as the original node. Perform following steps to recover from this situation:

  1. stop heartbeat on node2

  2. remove node2 from the cluster (see below)

  3. now create hb_uuid on node2 as explained above

  4. you assign the replaced node a new UUID
  5. remove node2 from the cluster (see below)

  6. on all nodes in the cluster delete /var/lib/heartbeat/delhostcache

  7. now run on any node attached to to cluster /var/lib/heartbeat/hb_addnode node2

  8. on node2 start heartbeat - finished

  9. in case you deactivated pingd activate it again and make sure heartbeat is started automatically when rebooting

  10. removing a node from the cluster

Note: heartbeat release 2.0.8 and earlier had a bug with pingd. The pingd CIB attribute value is reset to 0 when removing a cluster node with hb_delnode (even if the removed cluster node was not part of the configured ping group). Depending on your cluster configuration it may have unwanted effects. It is adviced to set the cluster into unmanaged mode during the replacement procedure to avoid unwanted resource stops/starts.

  1. in case pingd is used, stop it

  2. on any node attached to the cluster run /usr/lib/heartbeat/hb_delnode node2. In case node2 is already attached to the cluaster and it says "can't delete active node" or something similar then shutdown heartbeat on node2 and repeat the step again

  3. verify on the node where you run 'hb_delnode if node2 was removed from the cluster by checking /var/lib/heartbeat/hostache - there should be no entry for node2`.

    • in case there is still an entry left repeat step 2
  4. in case pingd was used, restart it

  5. if the removed cluster node shall not be readded with the same UUID again delete /var/lib/heartbeat/delhostcache on all cluster nodes

See Also

Heartbeat FAQ