Hi Dejan,

On Wed, 2011-02-23 at 11:54 +0100, Dejan Muhamedagic wrote:
> Hi Holger,
> 
> On Tue, Feb 22, 2011 at 06:25:37PM +0100, Holger Teutsch wrote:
> > Hi,
> > I resubmit the db2 agent for inclusion into the project. Besides fixing
> > some loose ends the major change is a reimplementation of attribute
> > management. Now the attributes are of type "-t nodes -l reboot". IMHO
> > all concerns raised during the first review are fixed now.
> > 
> > The new agent passes the ocft test 8-).
> 
> :) BTW, did you consider testing promote/demote too? Would that
> be possible?

I will always stay compatible ( 8-) ): so once the new agent is in the
repository I will work this (although not sure about viability).

> 
> > Collateral documentation is in
> > 
> > http://www.linux-ha.org/wiki/Db2_(resource_agent)
> 
> Great!
> 
> > For reference purposes I include a diff against the last submission.
> > 
> > Regards
> > Holger

See answers below, new version will come in a subsequent mail.
- holger

> > 
> > ---- reference only ----
> > --- a/db2   Wed Feb 09 19:34:36 2011 +0100
> > +++ b/db2   Tue Feb 22 18:15:50 2011 +0100
> > @@ -34,14 +34,14 @@
> >  #######################################################################
> >  # Initialization:
> >  
> > -: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/heartbeat}
> > -. ${OCF_FUNCTIONS_DIR}/.ocf-shellfuncs
> > +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
> > +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
> >  
> >  #######################################################################
> >  
> >  
> >  db2_usage() {
> > -    echo "db2 start|stop|monitor|promote|demote|validate-all|meta-data"
> > +    echo "db2 
> > start|stop|monitor|promote|demote|notify|validate-all|meta-data"
> >  }
> >  
> >  db2_meta_data() {
> > @@ -51,20 +51,30 @@
> >  <resource-agent name="db2">
> >  <version>1.0</version>
> >  <longdesc lang="en">
> > -Resource Agent that manages an IBM DB2 LUW database in Standard role as 
> > primitive or HADR roles in master/slave configuration.
> > +Resource Agent that manages an IBM DB2 LUW databases in Standard role as 
> > primitive or in HADR roles in master/slave configuration. Multiple 
> > partitions are supported.
> >  
> > -Multiple partitions are supported as well. Configure each partition as a 
> > separate resource.
> > +Standard mode:
> > +
> > +An instance including all or selected databases is made highly available.
> > +Configure each partition as a separate primitive resource.
> > +
> > +HADR mode:
> > +
> > +A single database in HADR configuration is made highly available by 
> > automating takeover operations.
> > +Configure a master / slave resource with notifications enabled and an
> > +additional monitoring operation with role "Master".
> >  
> >  In case of HADR be very deliberate in specifying intervals/timeouts. The 
> > detection of a failure including promote must complete within 
> > HADR_PEER_WINDOW.
> >  
> >  In addition to honoring requirements for crash recovery etc. for your 
> > specific database use the following relations as guidance:
> >  
> >  "monitor interval" &lt; HADR_PEER_WINDOW - (appr 30 sec)
> > +
> >  "promote timeout" &lt; HADR_PEER_WINDOW + (appr 20 sec)
> >  
> >  For further information and examples consult 
> > http://www.linux-ha.org/wiki/db2_(resource_agent)
> >  </longdesc>
> > -<shortdesc lang="en">Manages an IBM DB2 LUW database in Standard or HADR 
> > mode</shortdesc>
> > +<shortdesc lang="en">Resource Agent that manages an IBM DB2 LUW databases 
> > in Standard role as primitive or in HADR roles as master/slave 
> > configuration. Multiple partitions are supported.</shortdesc>
> >  
> >  <parameters>
> >  <parameter name="instance" unique="1" required="1">
> > @@ -93,7 +103,7 @@
> >  <longdesc lang="en">
> >  The number of the partion (DBPARTITIONNUM) to be managed.
> >  </longdesc>
> > -<shortdesc lang="en">number of partion</shortdesc>
> > +<shortdesc lang="en">Number of partion</shortdesc>
> 
> Better:
> 
>  +<shortdesc lang="en">partition number</shortdesc>
> 
> or perhaps:
> 
>  +<shortdesc lang="en">database partition</shortdesc>
> 
So I go for
<shortdesc lang="en">database partition number (DBPARTITIONNUM)</shortdesc>

> >  <content type="string" default="0" />
> >  </parameter>
> >  </parameters>
> > @@ -103,6 +113,7 @@
> >  <action name="stop" timeout="120"/>
> >  <action name="promote" timeout="120"/>
> >  <action name="demote" timeout="120"/>
> > +<action name="notify" timeout="10"/>
> >  <action name="monitor" depth="0" timeout="60" interval="20"/>
> >  <action name="monitor" depth="0" timeout="60" role="Master" interval="22"/>
> >  <action name="validate-all" timeout="5"/>
> > @@ -225,31 +236,44 @@
> >  
> >  #
> >  # maintain the fal (first active log) attribute
> > -# db2_fal_attrib DB {set val|get|delete}
> > +# db2_fal_attrib DB {set val|get}
> >  #
> >  db2_fal_attrib() {
> >      local db=$1
> > -    local attr
> > +    local attr val rc id node member me
> >  
> >      attr=db2hadr_${instance}_${db}_fal
> >  
> >      case "$2" in
> >          set)
> > -        crm_attribute -t crm_config -n $attr -v "$3" 
> > +        me=$(uname -n)
> > +
> > +        # loop over all member nodes and set attribute
> > +        crm_node -l |\
> 
> BTW, no need for \ after | or || or &&

Changed

> 
> > +        while read id node member
> > +        do
> > +            [ "$member" = member -a "$node" != "$me" ] || continue
> 
> Hmm, do you really want to set the attribute for nodes which are
> not members?
> 

The attribute should be set on "the other member nodes".
So "|| continue" shortcuts if this is *not* the case, or ?

> > +            crm_attribute -t nodes -l reboot --node=$node -n $attr -v "$3"
> > +            rc=$?
> > +            ocf_log info "DB2 instance $instance($db2node/$db: setting 
> > attrib for FAL to $FIRST_ACTIVE_LOG @ $node"
> > +            [ $rc != 0 ] && break
> > +        done
> 
> How about just (without loop):
> 
>            crm_attribute -t nodes -l reboot -n $attr -v "$3"
> 
> Note that the node value defaults to the node where you run the
> command.
> 

See above.

> If you want to check if this node is really a member:
> 
>       crm_node -l | grep -qs " $me member$" ||
>               ocf_log err "bad usage: we are not member of the cluster"
> 
> But perhaps that's not necessary.
>
> >          ;;
> >  
> >          get)
> > -        crm_attribute -t crm_config -n $attr -G -Q 2>&1
> > -        ;;
> > -
> > -        delete)
> > -        # -D is noisy to stdout
> > -        crm_attribute -t crm_config -n $attr -D > /dev/null
> > +        crm_attribute -t nodes -l reboot -n $attr -G -Q 2>&1
> > +        rc=$?
> > +        if [ $rc != 0 ]
> > +        then
> > +            ocf_log warn "DB2 instance $instance($db2node/$db: can't 
> > retrieve attribute $attr, are you sure notifications are enabled ?"
> > +        fi
> >          ;;
> >  
> >          *)
> >          exit $OCF_ERR_CONFIGURED
> >      esac
> > +
> > +    return $rc
> >  }
> >  
> >  #
> > @@ -362,7 +386,7 @@
> >          ocf_log info "DB2 instance $instance($db2node) started: $output"
> >      else
> >          case $output in
> > -            SQL1026N*)
> > +            *SQL1026N*)
> >              ocf_log info "DB2 instance $instance($db2node) already 
> > running: $output"
> >              ;;
> >  
> > @@ -394,6 +418,10 @@
> >          if [ $HADR_ROLE = PRIMARY ]
> >          then
> >              local master_fal
> > +
> > +            # communicate our FAL to other nodes the might start 
> > concurrently
> > +            db2_fal_attrib $db set $FIRST_ACTIVE_LOG
> > +
> >              if master_fal=$(db2_fal_attrib $db get) && [ "$master_fal" '>' 
> > $FIRST_ACTIVE_LOG ]
> >              then
> >                  ocf_log info "DB2 database $instance($db2node)/$db is 
> > Primary and outdated, starting as secondary"
> > @@ -417,8 +445,12 @@
> >                  ocf_log err "Possible split brain ! Manual intervention 
> > required."
> >                  ocf_log err "If this DB is outdated use \"db2 start hadr 
> > on db $db as standby\""
> >                  ocf_log err "If this DB is the surviving primary use \"db2 
> > start hadr on db $db as primary by force\""
> > -                # should we return OCF_ERR_INSTALLED instead ?
> > -                # might be a timing problem
> > +
> > +                # might be a timing problem because "First active log" is 
> > delayed
> > +                # sleep long so we won't end up in a high speed retry loop
> > +                # lrmd will kill us eventually on timeout
> > +                # on the next start attempt we might succeed when FAL was 
> > advanced
> > +                sleep 36000
> 
> Perhaps you should still remove this sleep. If there's nothing
> that can be done without administrator intervention, then better
> exit soon and let the cluster try to recover whichever way it can
> (depending also on how it is configured).
> 

Yes, but we can end up in a "high speed" restart loop. Instead of
putting in some random sleep I felt that relying on the administrator's
timeout choice is better. 

> >                  return $OCF_ERR_GENERIC
> >                  ;;
> >  
> > @@ -449,7 +481,7 @@
> >          ocf_log info "DB2 instance $instance($db2node) stopped: $output"
> >      else
> >          case $output in
> > -            SQL1032N*)
> > +            *SQL1032N*)
> >              #SQL1032N  No start database manager command was issued
> >              ocf_log info "$output"
> >              ;;
> > @@ -510,11 +542,11 @@
> >  
> >      if [ $stoprc -ne 0 ]
> >      then
> > -        ocf_log warn "DB instance $instance($db2node): db2stop failed, 
> > using db2nkill"
> > +        ocf_log warn "DB2 instance $instance($db2node): db2stop failed, 
> > using db2nkill"
> >          must_kill=1
> >      elif ! db2_instance_dead
> >      then
> > -        ocf_log warn "DB instance $instance($db2node): db2stop indicated 
> > success but there a still processes, using db2nkill"
> > +        ocf_log warn "DB2 instance $instance($db2node): db2stop indicated 
> > success but there a still processes, using db2nkill"
> >          must_kill=1
> >      fi
> >  
> > @@ -659,15 +691,6 @@
> >      # everything OK, return if running as slave
> >      grep MASTER $STATE_FILE >/dev/null 2>&1 || return $OCF_SUCCESS
> >  
> > -    # if we are the master we record our first active log in the CIB
> > -    # so a crashed server coming up as primary again after takeover of the
> > -    # former standby can detect that it is the outdated one.
> > -
> > -    # sets FIRST_ACTIVE_LOG
> > -    db2_get_cfg $dblist || return $?
> > -
> > -    db2_fal_attrib $dblist set $FIRST_ACTIVE_LOG || return $OCF_ERR_GENERIC
> > -    
> >      return $OCF_RUNNING_MASTER
> >  }
> >  
> > @@ -747,19 +770,36 @@
> >      local db=$dblist
> >      local hadr
> >      
> > +    # house keeping, set pacemaker's view to slave
> > +    echo SLAVE > $STATE_FILE
> 
> Didn't mention this before, but I did wonder if it would be
> possible to do without this state file. What worries me is that
> there's always a possibility that it can contain stale
> information in case the RA instance got killed. I can't say if it
> is possible that this stale information can have adverse effect.
> 

I'm afraid that is not possible. Pacemaker requires that resources come
up in slave mode. I.e. even a DB that comes up as Primary has to be
reported as slave. So the monitoring procedure has to use some external
state.

I reordered the "rm $STATE_FILE" to the very top of the stop procedure
to further minimize the risk of stale data.  


> > [...]
> 
> Cheers,
> 
> Dejan
> _______________________________________________________
> Linux-HA-Dev: [email protected]
> http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
> Home Page: http://linux-ha.org/


_______________________________________________________
Linux-HA-Dev: [email protected]
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/

Reply via email to