<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Furushima</title>
	<atom:link href="https://furushima.com.br/feed/" rel="self" type="application/rss+xml" />
	<link>https://furushima.com.br</link>
	<description>- Consultoria de Banco de Dados &#124; Furushima</description>
	<lastBuildDate>Mon, 03 Nov 2025 22:02:24 +0000</lastBuildDate>
	<language>pt-BR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://furushima.com.br/wp-content/uploads/2024/02/cropped-favicon-32x32.png</url>
	<title>Furushima</title>
	<link>https://furushima.com.br</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>secondary_vnic_all_configure.sh</title>
		<link>https://furushima.com.br/blog/secondary_vnic_all_configure-sh/</link>
		
		<dc:creator><![CDATA[Carlos Furushima]]></dc:creator>
		<pubDate>Mon, 03 Nov 2025 21:25:56 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">https://furushima.com.br/?p=2917</guid>

					<description><![CDATA[Script oficial da Oracle Cloud que detecta e configura automaticamente todas as VNICs secundárias anexadas a uma VM Linux. Ideal para multihoming, separação de redes (app/backup), rotas dedicadas e cenários de alta disponibilidade. Faça o Download do script abaixo : https://raw.githubusercontent.com/oracle/terraform-examples/master/examples/oci/connect_vcns_using_multiple_vnics/scripts/secondary_vnic_all_configure.sh]]></description>
										<content:encoded><![CDATA[
<p>Script oficial da Oracle Cloud que <strong>detecta e configura automaticamente todas as VNICs secundárias</strong> anexadas a uma VM Linux.<br></p>



<ul class="wp-block-list">
<li><strong>Sobe as interfaces</strong> correspondentes às VNICs secundárias;</li>



<li><strong>Obtém o IP</strong> (via DHCP) ou aplica o IP estático já definido;</li>



<li><strong>Cria rotas e regras de policy routing</strong> por interface, isolando o tráfego por sub-rede;</li>



<li><strong>Persiste a configuração</strong> para sobreviver a reinicializações;</li>



<li>É <strong>idempotente</strong> (pode ser executado várias vezes) e dispensa reboot após anexar a VNIC.</li>
</ul>



<p>Ideal para <strong>multihoming</strong>, separação de redes (app/backup), rotas dedicadas e cenários de alta disponibilidade.</p>



<p></p>



<p>Faça o Download do script abaixo : </p>



<div class="wp-block-file aligncenter"><a id="wp-block-file--media-36d113fa-25db-4bd4-9ba6-1db1ffc5ed86" href="https://furushima.com.br/wp-content/uploads/2025/11/vnic.zip">vnic</a><a href="https://furushima.com.br/wp-content/uploads/2025/11/vnic.zip" class="wp-block-file__button wp-element-button" download aria-describedby="wp-block-file--media-36d113fa-25db-4bd4-9ba6-1db1ffc5ed86">Baixar</a></div>



<p></p>



<p class="has-text-align-center"><a href="https://raw.githubusercontent.com/oracle/terraform-examples/master/examples/oci/connect_vcns_using_multiple_vnics/scripts/secondary_vnic_all_configure.sh">https://raw.githubusercontent.com/oracle/terraform-examples/master/examples/oci/connect_vcns_using_multiple_vnics/scripts/secondary_vnic_all_configure.sh</a></p>



<p></p>



<p></p>



<p></p>



<div class="wp-block-kevinbatdorf-code-block-pro alignwide" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="#!/usr/bin/env bash

# Copyright (c) 2018, Oracle and/or its affiliates.
# The Universal Permissive License (UPL), Version 1.0
#
# Oracle OCI Virtual Cloud Networks IP configuration script
#
# 2017-10-24 initial release
# 2017-11-21 filter out VLANs if VM
# 2017-11-21 inhibit namespaces for ubuntu 16
# 2018-02-12 fix sshd typo in help
# 2018-02-20 update copyright notice
# 2018-03-21 fix to add src routing on primary VNIC when not using namespaces
# 2018-04-05 add note on multiple VCNs
# 2018-05-10 fix to delete config by deleting default route before deleting table, added -v option
# 2018-05-22 fix to ignore interfaces enslaved to a master device
# 2018-09-14 allow namespaces for Ubuntu 16 since problems with DHCP are fixed, and inhibit for all OL/Centos 6
# 2018-09-19 fix os name and version setting for centos 6 images
# 2018-09-19 fix ip addr parsing to remove MAC VLAN interfaces
# 2018-10-25 fix secondary private ip src routing
# 2018-10-31 fix misc routing setup, fix multiple ifaces on same subnet

declare -r THIS=$(basename &quot;$0&quot;)
declare -r MD_URL='http://169.254.169.254/opc/v1/vnics/'
declare -r NA='-'
declare -r RTS_FILE='/etc/iproute2/rt_tables'
declare -ir RT_ID_MIN=10 # in case lower ones are reserved
declare -ir RT_ID_MAX=255
declare -r RT_FORMAT_BM='ort${nic}vl${vltag}'
declare -r RT_FORMAT_VM='ort${nic}'
declare -r DEF_NS_FORMAT_BM='ons${nic}vl${vltag}'
declare -r DEF_NS_FORMAT_VM='ons${nic}'
declare -r MACVLAN_FORMAT='${iface}.${vltag}' # note awk script looks for this (max 15 chars)
declare -r VLAN_FORMAT='${iface}v${vltag}' # (max 15 chars)
declare -ir MTU=9000
declare -r ADD='ADD'
declare -r DELETE='DELETE'
declare -r YES='YES'
declare -r CURL=$(which curl)
declare -r IP=$(which ip)
declare -r SSHD=$(which sshd)
declare -r MODPROBE=$(which modprobe)
declare -r OS_RELEASE='/etc/os-release'
if [ -f &quot;$OS_RELEASE&quot; ]; then
    declare -r OS_ID=$(grep -ws ID $OS_RELEASE | cut -f 2 -d '=' | tr -d '&quot;' | tr '[:upper:]' '[:lower:]')
    declare -r OS_VERSION=$(grep -ws VERSION_ID $OS_RELEASE | cut -f 2 -d '=' | tr -d '&quot;')
else
    declare -r OS_RELEASE_alt='/etc/redhat-release'
    if [ -f &quot;$OS_RELEASE_alt&quot; ]; then
        declare -r OS_ID=$(cat $OS_RELEASE_alt|cut -f 1 -d ' ' | tr '[:upper:]' '[:lower:]')
        declare -r OS_VERSION=$(cat $OS_RELEASE_alt | cut -f 3 -d ' ')
    fi
fi
if [ -n &quot;$OS_VERSION&quot; ]; then
    declare -r OS_MAJ_VERSION=$(echo $OS_VERSION | cut -f 1 -d '.')
fi
declare -r SYS_CLASS_NET='/sys/class/net'
declare -A VIRTUAL_IFACES
declare IS_VM=''
declare -a MACS # all (unique) macs
declare -A MD_I_BY_MAC # index into arrays by MAC
declare -a MD_MACS
declare -a MD_ADDRS
declare -a MD_VLTAGS
declare -a MD_SCIDRS
declare -a MD_SPREFIXS
declare -a MD_SBITSS
declare -a MD_VIRTRTS
declare -a MD_VNICS
declare -a MD_NIC_IS # not set at all if vm
declare -a MD_CONFIGS # $ADD if vnic added
declare -A DUP_ADDRS # hash of addrs that appear more than once
declare -A DUP_SADDRS # hash of subnet addrs that appear more than once
# items use $NA to mean null
declare -A IP_I_BY_MAC # index into arrays by MAC
declare -a IP_MACS # runs of dups if sec addrs
declare -a IP_NSS
declare -a IP_IFACES
declare -a IP_ADDRS
declare -a IP_SADDRS
declare -a IP_SBITSS
declare -a IP_VIRTRTS
declare -a IP_STATES
declare -a IP_VLANS
declare -a IP_VLTAGS # vltag (0 if phys iface)
declare -a IP_SECADS # set to $YES if secondary addr
declare -a IP_SRCS # set to $YES if src hint
declare -a IP_NIC_IS # nic index of iface
declare -a IP_CONFIGS # $DELETE if vnic deleted
declare -a NIC_IP_IS # index of physical iface for nic index
declare -A NIC_I_BY_PHYS_IP_I # nic index for physical iface ip_i
# be sure to clear any IP_ arrays above in the read function
# options:
declare QUIET=''
declare DEBUG=''
declare START_SSHD=''
declare USE_NS=''
declare NS_FORMAT=''
declare -a SEC_ADDRS
declare -a SEC_VNICS

declare -r IFACE_AWK_SCRIPT='/tmp/oci_vcn_iface.awk'
cat &gt;$IFACE_AWK_SCRIPT &lt;&lt;'EOF'
function prtiface(mac, iface, addr, sbits, state, vlan, vltag, secad) {
    if (iface != &quot;&quot;) printf &quot;%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n&quot;, mac, iface, addr, sbits, state, vlan, vltag, secad
}
BEGIN { iface = &quot;&quot;; addr = &quot;-&quot; }
/^[0-9]/ {
    # if not the first and prev was not a mac vlan then print previous (note print at end too)
    if (addr == &quot;-&quot;) prtiface(mac, iface, addr, sbits, state, vlan, vltag, secad)
    addr = &quot;-&quot;
    sbits = &quot;-&quot;
    state = &quot;-&quot;
    macvlan = &quot;-&quot;
    vlan = &quot;-&quot;
    vltag = &quot;-&quot;
    secad = &quot;-&quot;
    if ($0 ~ /BROADCAST/ &amp;&amp; $0 !~ /UNKNOWN/ &amp;&amp; $0 !~ /NO-CARRIER/ &amp;&amp; $0 !~ /master /) {
        i = index($2, &quot;@&quot;)
        if (1 &lt; i) {
            j = index($2, &quot;.&quot;)
            if (j &lt; i) { # mac vlan (not used, no addrs)
                macvlan = substr($2, 1, i - 1)
                iface = substr($2, i + 1, length($2) - i - 1) # skip : at end
                addr = &quot;&quot; # skip the mac vlan iface
            } else { # vlan
                vlan = substr($2, 1, i - 1)
                # extract iface/vltag from macvlan
                iface = substr($2, i + 1, j - i - 1)
                vltag = substr($2, j + 1, length($2) - j - 1) # skip : at end
            }
        } else {
            i = index($2, &quot;:&quot;)
            if (i &lt;= 1) { print &quot;cannot find interface name&quot;; exit 1 }
            iface = substr($2, 1, i - 1)
        }
        if ($0 ~ /LOWER_UP/) state = &quot;UP&quot;
        else state = &quot;DOWN&quot;
    } else iface = &quot;&quot;
    next
}
/ link\/ether / { mac = tolower($2) }
/ inet [0-9]/ {
    i = index($2, &quot;/&quot;)
    if (i &lt;= 1) { print &quot;cannot find interface inet address&quot;; exit 1 }
    if (addr != &quot;-&quot;) secad = &quot;YES&quot;
    addr = substr($2, 0, i - 1)
    sbits = substr($2, i + 1, length($2) - i)
    prtiface(mac, iface, addr, sbits, state, vlan, vltag, secad)
}
END { if (addr == &quot;-&quot;) prtiface(mac, iface, addr, sbits, state, vlan, vltag, secad) }
EOF

oci_vcn_err() {
    echo &quot;Error: $1&quot; &gt;&amp;2
    exit 1
}

oci_vcn_warn() {
    echo &quot;Warning: $1&quot; &gt;&amp;2
}

oci_vcn_info() {
    [ -n &quot;$QUIET&quot; ] || echo &quot;Info: $1&quot; &gt;&amp;2
}

oci_vcn_debug() {
    [ -z &quot;$DEBUG&quot; ] || echo &quot;Debug: $1&quot; &gt;&amp;2
}

oci_vcn_virtual_ifaces_read() {
    VIRTUAL_IFACES=()
    local iface
    for iface in $(ls $SYS_CLASS_NET); do
        if ls -l $SYS_CLASS_NET/$iface | grep -wq virtual; then
            VIRTUAL_IFACES[$iface]='t'
        fi
    done
}

oci_vcn_md_read() {
    # sets all MD data arrays and their index I_BY_MAC
    local -r tmpfile=$(mktemp /tmp/oci_vcn_md.XXXXX)

    # MD notes:
    # vnic order: primary first, then time created (and therefore vltag/nic)
    # BM notes: (1) may be interleaved wrt nic index (i.e. all nic 0 not guaranteed before all nic 1)
    # (2) nicIndex was supported starting around 8/23/17, but will not appear on previously
    # launched instances unless refreshed by a vnic attach or detach after that date

    # parse: force json fields on separate lines
    # WARNING: assumes no string values with commas or double quotes
    # WARNING: assumes no sub-objects with identical field names
    [ -n &quot;$CURL&quot; ] || oci_vcn_err &quot;cannot find curl command&quot;
    $CURL -s $MD_URL | tr , '\n' &gt;&quot;$tmpfile&quot; || oci_vcn_err &quot;cannot read metadata&quot;
    MD_MACS=($(grep -w macAddr &quot;$tmpfile&quot; | cut -f 4 -d '&quot;')) || exit $? # string
    local -i i
    for i in $(seq 0 $((${#MD_MACS[@]} - 1))); do
        MD_MACS[$i]=&quot;${MD_MACS[$i],,}&quot;
    done
    MD_ADDRS=($(grep -w privateIp &quot;$tmpfile&quot; | cut -f 4 -d '&quot;')) # string
    MD_VLTAGS=($(grep -w vlanTag &quot;$tmpfile&quot; | cut -f 2 -d ':' | tr -d ' ')) # integer
    MD_VIRTRTS=($(grep -w virtualRouterIp &quot;$tmpfile&quot; | cut -f 4 -d '&quot;')) # string
    local s
    for s in $(grep -w subnetCidrBlock &quot;$tmpfile&quot; | cut -f 4 -d '&quot;'); do # string
        MD_SCIDRS+=(${s})
        MD_SPREFIXS+=(${s%/*})
        MD_SBITSS+=(${s#*/})
    done
    MD_VNICS=($(grep -w vnicId &quot;$tmpfile&quot; | cut -f 4 -d '&quot;'))
    MD_NIC_IS=($(grep -w nicIndex &quot;$tmpfile&quot; | cut -f 2 -d ':' | tr -d ' '))

    # do some validity checks on md data
    [ ${#MD_MACS[@]} -eq ${#MD_ADDRS[@]} ] || oci_vcn_err &quot;invalid metadata: MAC or IP addresses are missing&quot;
    [ ${#MD_MACS[@]} -eq ${#MD_VLTAGS[@]} ] || oci_vcn_err &quot;invalid metadata: MAC or VLAN tags are missing&quot;
    [ ${#MD_MACS[@]} -eq ${#MD_VIRTRTS[@]} ] || oci_vcn_err &quot;invalid metadata: MAC or virtual router addresses are missing&quot;
    [ ${#MD_MACS[@]} -eq ${#MD_SPREFIXS[@]} ] || oci_vcn_err &quot;invalid metadata: MAC or subnets are missing&quot;
    [ ${#MD_MACS[@]} -eq ${#MD_VNICS[@]} ] || oci_vcn_err &quot;invalid metadata: MAC or VNIC ids are missing&quot;
    for i in $(seq 0 $((${#MD_MACS[@]} - 1))); do
        [[ ${MD_ADDRS[$i]} =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]] || oci_vcn_err &quot;invalid metadata: address IP format incorrect: ${MD_ADDRS[$i]}&quot;
        [[ ${MD_VLTAGS[$i]} =~ ^[0-9]+$ ]] || oci_vcn_err &quot;invalid metadata: VLAN tag incorrect: ${MD_VLTAGS[$i]}&quot;
        [[ ${MD_VIRTRTS[$i]} =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]] || oci_vcn_err &quot;invalid metadata: virtual router address format incorrect: ${MD_VIRTRTS[$i]}&quot;
        [[ ${MD_SPREFIXS[$i]} =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]] || oci_vcn_err &quot;invalid metadata: subnet prefix format incorrect: ${MD_SPREFIXS[$i]}&quot;
    done

    # set vm flag based on existence of nic index (see override in oci_vcn_ip_read)
    # get the virtual interfaces if VM
    if [ ${#MD_NIC_IS[@]} -eq 0 ]; then
        IS_VM='t'
        oci_vcn_virtual_ifaces_read
    fi

    # create reverse lookup
    for i in &quot;${!MD_MACS[@]}&quot;; do
        MD_I_BY_MAC[${MD_MACS[$i]}]=$i
    done
    rm &quot;$tmpfile&quot;

    # find the duplicate addrs, if any
    local -A addrs=()
    local addr
    for addr in &quot;${MD_ADDRS[@]}&quot;; do
        if [ -n &quot;${addrs[$addr]}&quot; ]; then DUP_ADDRS[$addr]='t'; fi
        addrs[$addr]='t'
    done

    # find the duplicate subnet addrs, if any
    local -A saddrs=()
    for addr in &quot;${MD_SPREFIXS[@]}&quot;; do
        if [ -n &quot;${saddrs[$addr]}&quot; ]; then DUP_SADDRS[addr]='t'; fi
        saddrs[addr]='t'
    done
}

oci_vcn_ip_route_table_name() {
    local -ir nic=$1 # format looks for &quot;${nic}&quot;, note this is really $nic_i
    local -ir vltag=$2
    local format=&quot;$RT_FORMAT_VM&quot;

    [ -n &quot;$IS_VM&quot; ] || format=&quot;$RT_FORMAT_BM&quot;
    eval echo &quot;$format&quot;
}

oci_vcn_ip_route_table_name_ip_i() {
    # use only when ip already setup
    local -ir ip_i=$1
    local -ir nic_i=${IP_NIC_IS[$ip_i]}
    local -ir vltag=${IP_VLTAGS[$ip_i]}

    oci_vcn_ip_route_table_name $nic_i $vltag
}

oci_vcn_ip_route_table_exists() {
    local -r rt_name=$1
    if grep -qsw $rt_name $RTS_FILE; then
        echo &quot;$rt_name&quot;
    fi
}

oci_vcn_ip_route_table_find_unused_id() {
    # read all the current route table id/name pairs
    # mapfile will create array with each line an element
    local lines
    mapfile -t lines &lt; &lt;(cat $RTS_FILE | grep -E '^[0-9]' | tr '\t' ' ' | tr -s ' ' ' ') || oci_vcn_err &quot;cannot read route tables file $RTS_FILE&quot;
    local line
    local -A rt_by_id
    for line in &quot;${lines[@]}&quot;; do
        local -a pair=($line)
        local id=${pair[0]}
        local name=${pair[1]}
        rt_by_id[$id]=$name
    done

    # find first id not used
    local -i unused=-1
    local -i i
    for i in $(seq $RT_ID_MIN $RT_ID_MAX); do
        if [ -z &quot;${rt_by_id[$i]}&quot; ]; then
            unused=$i
            break
        fi
    done
    [ $unused -ne -1 ] ||  oci_vcn_err &quot;cannot find unused id in route tables file $RTS_FILE&quot;
    echo $unused
}

oci_vcn_ip_route_table_create() {
    local -ir nic_i=$1
    local -ir vltag=$2
    local -r skip_if_exists=$3
    local -r rt_name=$(oci_vcn_ip_route_table_name $nic_i $vltag)

    # Check if the route table exists
    local rt_exists
    rt_exists=$(oci_vcn_ip_route_table_exists $rt_name) || exit $?
    if [ -n &quot;$rt_exists&quot; ]; then # already exists
        if [ -n &quot;$skip_if_exists&quot; ]; then
            oci_vcn_debug &quot;create route table $rt_name already exists, skipping&quot;
            return
        fi
        oci_vcn_warn &quot;route table $rt_name already exists, reusing&quot;
    else # create
        local -i rt_id
        rt_id=$(oci_vcn_ip_route_table_find_unused_id) || exit $?
        oci_vcn_debug &quot;create route table $rt_name ($rt_id)&quot;
        echo &quot;$rt_id    $rt_name&quot; &gt;&gt; $RTS_FILE
    fi
    echo &quot;$rt_name&quot;
}

oci_vcn_ip_route_table_del() {
    local -r rt_name=$1
    local -r tmpfile=$(mktemp /tmp/oci_vcn_rt_tables.XXXXX)

    if ! grep -qsw $rt_name $RTS_FILE; then
        oci_vcn_debug &quot;rt $rt_name not in $RTS_FILE&quot;
        return
    fi
    oci_vcn_debug &quot;rt $rt_name delete&quot;
    cp -p $RTS_FILE &quot;$tmpfile&quot; # in case grep fails
    grep -vw $rt_name $RTS_FILE &gt; &quot;$tmpfile&quot;
    mv &quot;$tmpfile&quot; $RTS_FILE
    echo 't'
}

oci_vcn_ip_routing_add() {
    local -ir md_i=$1
    local -ir nic_i=$2
    local -r iface=$3
    local -r ns=$4
    local -r skip_if_exists=$5
    local -ir vltag=&quot;${MD_VLTAGS[$md_i]}&quot;
    local -r addr=&quot;${MD_ADDRS[$md_i]}&quot;
    local -r sprefix=&quot;${MD_SPREFIXS[$md_i]}&quot;
    local -r virtrt=&quot;${MD_VIRTRTS[$md_i]}&quot;
    local -r scidr=&quot;${MD_SCIDRS[$md_i]}&quot;

    # set a default route to the gateway/virtual router
    if [ -n &quot;$ns&quot; ]; then
        local -r nscmd=&quot;netns exec $ns $IP&quot;
        # using a namespace: iface is assumed only one in namespace, so just set a
        # default route to the gateway in the main route table
        oci_vcn_debug &quot;default route add&quot;
        $IP $nscmd route add default via $virtrt || oci_vcn_err &quot;cannot add namespace $ns default gateway $virtrt&quot;
        oci_vcn_info &quot;added namespace $ns default route to gateway $virtrt&quot;
    else
        # the default route (in main route table) already defined through primary vnic.
        # this adds a rule to lookup a route table for any packets sourced from addr
        # and then the route table has the default route for that addr.
        # this allows packets from protocol services that reply with src addr
        # set to route back out through the iface (prevents asymmetric routing).

        # check for dup addrs and subnet addrs
        if [ -n &quot;${DUP_ADDRS[$addr]}&quot; ]; then
            oci_vcn_warn &quot;IP address $addr is a duplicate, skipping creating source route rule&quot;
            return
        fi
        [ -z &quot;${DUP_SADDRS[$sprefix]}&quot; ] || oci_vcn_warn &quot;duplicate subnet prefix $sprefix&quot;

        # create route table and add a default route via the gateway, and subnet route
        local rt_name
        rt_name=$(oci_vcn_ip_route_table_create $nic_i $vltag $skip_if_exists) || exit $?
        [ -n &quot;$rt_name&quot; ] || return
        oci_vcn_debug &quot;route table add rules&quot;
        $IP route add default via $virtrt dev $iface table $rt_name || oci_vcn_err &quot;cannot add default route via $virtrt on $iface to table $rt_name&quot;
        $IP route add $scidr dev $iface table $rt_name || oci_vcn_err &quot;cannot add subnet $scidr route on $iface to table $rt_name&quot;

        # create source-based rule to use table
        oci_vcn_debug &quot;src rule add&quot;
        $IP rule add from $addr lookup $rt_name || oci_vcn_err &quot;cannot add rule from $addr use table $rt_name&quot;
        oci_vcn_info &quot;added rule for routing from $addr lookup $rt_name with default via $virtrt&quot;
    fi
}

oci_vcn_ip_routing_del() {
    local -ir ip_i=$1
    local -r ns=&quot;${IP_NSS[$ip_i]#$NA}&quot;
    local -r iface=&quot;${IP_IFACES[$ip_i]}&quot;

    # for namespaces the subnet and default routes will be auto deleted with the namespace
    if [ -z &quot;$ns&quot; ]; then
        # delete rule
        local -r rt_name=$(oci_vcn_ip_route_table_name_ip_i $ip_i)
        local had_rule=''
        if $IP rule | grep -qsw $rt_name; then # rule(s) exists
            # note that there may be secondary private ips rules using the same table
            oci_vcn_debug &quot;rules to table $rt_name delete&quot;
            while $IP rule del lookup $rt_name 2&gt;/dev/null; do true; done
            had_rule='t'
        fi

        # delete route table
        local had_table
        had_table=$(oci_vcn_ip_route_table_del $rt_name) || exit $?
        ([ -z &quot;$had_rule&quot; ] &amp;&amp; [ -z &quot;$had_table&quot; ]) || oci_vcn_info &quot;removed routing on interface $iface&quot;
    fi
}

oci_vcn_ip_routing_sec_addr_add() {
    local -ir iface_ip_i=$1
    local -r addr=$2
    local -r ns=&quot;${IP_NSS[$iface_ip_i]#$NA}&quot;

    # need to add source rule so reuse the routing table from the primary private ip
    # not needed if in namespace
    # not needed if on pri iface (uses main route table for dest and default route)
    if [ -z &quot;$ns&quot; ] &amp;&amp; [ $iface_ip_i -ne 0 ]; then
        # create source-based rule to use iface's routing table
        local -r rt_name=$(oci_vcn_ip_route_table_name_ip_i $iface_ip_i)
        oci_vcn_debug &quot;sec addr src rule add&quot;
        $IP rule add from $addr lookup $rt_name || oci_vcn_err &quot;cannot add rule from secondary $addr use table $rt_name&quot;
        oci_vcn_info &quot;added rule for routing from secondary IP address $addr lookup $rt_name&quot;
    fi
}

oci_vcn_ip_routing_sec_addr_del() {
    local -ir ip_i=$1
    local -r addr=$2
    local -r ns=&quot;${IP_NSS[$ip_i]#$NA}&quot;

    # deconfig the routing (see comments in add)
    if [ -z &quot;$ns&quot; ] &amp;&amp; [ $ip_i -ne 0 ]; then
        $IP rule del from $addr 2&gt;/dev/null # ok if already deleted
        oci_vcn_info &quot;deleted rule for routing from secondary IP address $addr&quot;
    fi
}

oci_vcn_ip_routes_read() {
    #ip r list 192.168.1.0/24
    local -ir ip_i=$1
    local -r ns=&quot;${IP_NSS[$ip_i]#$NA}&quot;
    local -r iface=&quot;${IP_IFACES[$ip_i]}&quot;
    local nscmd=''
    local virtrt=&quot;$NA&quot;

    if [ -n &quot;$ns&quot; ]; then
        nscmd=&quot;netns exec $ns $IP&quot;
    else
        # no namespace: check for route table
        local -r rt_name=$(oci_vcn_ip_route_table_name_ip_i $ip_i)
        local rt_exists
        rt_exists=$(oci_vcn_ip_route_table_exists $rt_name) || exit $?
        if [ -n &quot;$rt_exists&quot; ]; then # exists
            # check for rule
            if $IP rule | grep -qsw $rt_name; then # rule exists that uses route table
                # look for default route in table, note table may exist but be empty
                # &quot;default via 10.0.0.1 dev ens3&quot;
                local -a def_entry
                def_entry=($($IP route show table $rt_name | grep -sw ^default))
                if [ -n &quot;${def_entry[2]}&quot; ]; then
                    virtrt=&quot;${def_entry[2]}&quot;
                    oci_vcn_debug &quot;default route: $virtrt&quot;
                else # emtpy table: delete rule and table
                    virtrt=&quot;$NA&quot;
                    oci_vcn_ip_routing_del $ip_i
                fi
            else # clean up route table since no rule uses it
                $(oci_vcn_ip_route_table_del $rt_name)
            fi
        fi
    fi

    # read the routes
    local sprefix=&quot;$NA&quot;
    local sbits=&quot;$NA&quot;
    local src=&quot;$NA&quot;
    # mapfile will create array with each line an element
    mapfile -t routes &lt; &lt;($IP $nscmd route | grep -w $iface) || oci_vcn_err &quot;cannot read IP routes for interface $iface&quot;
    local line
    for line in &quot;${routes[@]}&quot;; do
        local -a route=($line)
        if [ &quot;${route[0]}&quot; = 'default' ]; then
            # &quot;default via 10.0.0.1 dev ens3&quot;
            virtrt=&quot;${route[2]}&quot;
            oci_vcn_debug &quot;default route via: $virtrt&quot;
        elif [ &quot;${route[0]#169.}&quot; = &quot;${route[0]}&quot; ]; then # not cavium route
            # &quot;10.0.0.0/24 dev ens3 proto kernel scope link src 10.0.0.2&quot;
            local -i i
            for i in $(seq 0 $((${#route[@]} - 1))); do
                local x=&quot;${route[$i]}&quot;
                if [ $i -eq 0 ]; then
                    sprefix=${x%/*}
                    sbits=${x#*/}
                    if [ &quot;$sprefix&quot; = &quot;$sbits&quot; ]; then # not valid line
                        sprefix=&quot;$NA&quot;
                        sbits=&quot;$NA&quot;
                        break
                    else
                        oci_vcn_debug &quot;subnet route: $sprefix/$sbits&quot;
                    fi
                elif [ &quot;$x&quot; = 'src' ]; then src=&quot;$YES&quot;
                fi
            done
        fi
    done
    IP_VIRTRTS[$ip_i]=&quot;$virtrt&quot;
    IP_SADDRS[$ip_i]=&quot;$sprefix&quot;
    IP_SBITSS[$ip_i]=&quot;$sbits&quot;
    IP_SRCS[$ip_i]=&quot;$src&quot;
}

oci_vcn_macvlan_name() {
    local -r iface=$1
    local -r vltag=$2
    eval echo &quot;$MACVLAN_FORMAT&quot;
}

oci_vcn_vlan_name() {
    local -r iface=$1
    local -r vltag=$2
    eval echo &quot;$VLAN_FORMAT&quot;
}

oci_vcn_ip_ns_name() {
    local -ir nic=$1 # format looks for &quot;${nic}&quot;
    local -ir vltag=$2

    if [ -n &quot;$USE_NS&quot; ] &amp;&amp; [ -z &quot;$NS_FORMAT&quot; ]; then
        if [ -n &quot;$IS_VM&quot; ]; then NS_FORMAT=&quot;$DEF_NS_FORMAT_VM&quot;
        else NS_FORMAT=&quot;$DEF_NS_FORMAT_BM&quot;; fi
    fi
    eval echo &quot;$NS_FORMAT&quot;
}

oci_vcn_ip_ns_svcs_stop() {
    local -r ns=$1
    local pids
    pids=$($IP netns pids $ns) || oci_vcn_err &quot;cannot get ids for processes in namespace $ns&quot;
    if [ -n &quot;$pids&quot; ]; then
        kill -TERM $pids || oci_vcn_err &quot;cannot terminate namespace $ns processes: $pids&quot;
        oci_vcn_info &quot;terminated namespace $ns processes: $pids&quot;
    fi
}

oci_vcn_ip_ns_svcs_start() {
    local -r ns=$1
    if [ -n &quot;$START_SSHD&quot; ]; then # start SSH daemon
        $IP netns exec $ns $SSHD || oci_vcn_err &quot;cannot start ssh daemon&quot;
        oci_vcn_info &quot;started namespace $ns ssh daemon&quot;
    fi
}

oci_vcn_ip_ns_del() {
    local -r ns=$1
    # note also deletes vlans and routes
    $IP netns del $ns || oci_vcn_err &quot;cannot delete namespace $ns&quot;
    oci_vcn_info &quot;deleted namespace $ns&quot;
}

oci_vcn_ip_ns_create() {
    local -ir nic_i=$1
    local -ir vltag=$2

    [ -n &quot;$MODPROBE&quot; ] || oci_vcn_err &quot;cannot find modprobe command&quot;
    $MODPROBE 8021q || oci_vcn_err &quot;failed to load 8021q module&quot;
    local ns
    ns=$(oci_vcn_ip_ns_name $nic_i $vltag) || exit $?
    $IP netns add $ns || oci_vcn_err &quot;cannot create namespace $ns&quot;
    oci_vcn_info &quot;created namespace $ns&quot;
    echo &quot;$ns&quot;
}

oci_vcn_ip_addr_add_iface() {
    local -ir md_i=$1
    local -ir ip_i=$2 # index of physical iface/nic
    local -r ns=$3
    local iface=&quot;${IP_IFACES[$ip_i]}&quot;
    local -r physns=&quot;${IP_NSS[$ip_i]#$NA}&quot;
    local -r mac=&quot;${MD_MACS[$md_i]}&quot;
    local -ir vltag=&quot;${MD_VLTAGS[$md_i]}&quot;
    local -r addr=&quot;${MD_ADDRS[$md_i]}&quot;
    local -r sbits=&quot;${MD_SBITSS[$md_i]}&quot;
    local vlan=''

    # must be adding to physical iface/nic
    [ -z &quot;${IP_VLANS[$ip_i]#$NA}&quot; ] || oci_vcn_err &quot;cannot add IP address $addr to virtual interface ${IP_VLANS[$ip_i]}&quot;

    # create virtual interface if needed (bm cases)
    local macvlan=''
    if [ -z &quot;$IS_VM&quot; ] &amp;&amp; [ $vltag -ne 0 ]; then
        # bm vnics need a virtual iface except for vltag=0
        # if physical iface/nic is in a namespace we must go there to create
        local physnscmd=''
        if [ -n &quot;$physns&quot; ]; then
            physnscmd=&quot;netns exec $physns $IP&quot;
        fi

        # create a mac vlan from physical iface/nic
        oci_vcn_debug &quot;macvlan link add $macvlan&quot;
        macvlan=$(oci_vcn_macvlan_name $iface $vltag) || exit $?
        $IP $physnscmd link add link $iface name $macvlan address $mac type macvlan \
            || oci_vcn_err &quot;cannot create MAC VLAN interface $macvlan for MAC address $mac&quot;

        # if physical iface/nic is in a namespace pull out the created mac vlan
        if [ -n &quot;$physns&quot; ]; then
            $IP $physnscmd link set $macvlan netns 1
        fi

        # create an ip vlan on top of the mac vlan
        oci_vcn_debug &quot;vlan link add&quot;
        vlan=$(oci_vcn_vlan_name $iface $vltag) || exit $?
        $IP link add link $macvlan name $vlan type vlan id $vltag \
            || oci_vcn_err &quot;cannot create VLAN $vlan on MAC VLAN $macvlan&quot;
    fi

    # use namespace, if option
    local nscmd=''
    local -r dev=&quot;${vlan:-$iface}&quot;
    if [ -n &quot;$ns&quot; ]; then
        nscmd=&quot;netns exec $ns $IP&quot;
        # move the iface(s) to the target namespace
        if [ -n &quot;$macvlan&quot; ]; then
            oci_vcn_debug &quot;macvlan link move $ns&quot;
            $IP link set dev $macvlan netns $ns || oci_vcn_err &quot;cannot move MAC VLAN $macvlan into namespace $ns&quot;
        fi
        oci_vcn_debug &quot;$dev link move $ns&quot;
        $IP link set dev $dev netns $ns || oci_vcn_err &quot;cannot move interface $dev into namespace $ns&quot;
    fi

    # add IP address to iface:
    # the netmask is specified to create a route in the main route table
    # if this iface is on the same subnet as another iface then the route will not have an effect
    # (until the other iface is removed)
    oci_vcn_debug &quot;addr $addr/$sbits add on $dev ns '$ns'&quot;
    $IP $nscmd addr add $addr/$sbits dev $dev || oci_vcn_err &quot;cannot add IP address $addr/$sbits on interface $dev&quot;

    if [ -n &quot;$macvlan&quot; ]; then # set vlans up
        oci_vcn_debug &quot;vlans set up&quot;
        $IP $nscmd link set dev $macvlan mtu $MTU up || oci_vcn_err &quot;cannot set MAC VLAN $macvlan up&quot;
        $IP $nscmd link set dev $vlan mtu $MTU up || oci_vcn_err &quot;cannot set VLAN $vlan up&quot;
    else
        oci_vcn_debug &quot;$iface set up&quot;
        $IP $nscmd link set dev $iface mtu $MTU up || oci_vcn_err &quot;cannot set interface $iface MTU&quot;
    fi

    oci_vcn_info &quot;added IP address $addr on interface $dev with MTU $MTU&quot;
    echo &quot;$dev&quot;
}

oci_vcn_ip_addr_del_iface() {
    local -ir ip_i=$1
    local -r iface=&quot;${IP_IFACES[$ip_i]}&quot;
    local -r ns=&quot;${IP_NSS[$ip_i]#$NA}&quot;
    local -r vlan=&quot;${IP_VLANS[$ip_i]#$NA}&quot;
    local -r secad=&quot;${IP_SECADS[$ip_i]#$NA}&quot;
    local nscmd=''

    if [ -n &quot;$ns&quot; ]; then
        nscmd=&quot;netns exec $ns $IP&quot;
    fi
    if [ &quot;$secad&quot; != &quot;$YES&quot; ] &amp;&amp; [ -n &quot;$vlan&quot; ]; then
        # delete vlan and macvlan, removes the addrs (pri and sec) as well
        oci_vcn_debug &quot;$ns link delete&quot;
        local -ir vltag=&quot;${IP_VLTAGS[$ip_i]}&quot;
        local macvlan
        macvlan=$(oci_vcn_macvlan_name $iface $vltag) || exit $?
        $IP $nscmd link del link $vlan dev $macvlan || oci_vcn_err &quot;cannot remove VLAN $vlan&quot;
        oci_vcn_info &quot;removed VLAN $vlan&quot;
    else
        # delete addr from phys iface
        # deleting namespace will move phys iface back to main
        # note that we may be deleting sec addr from a vlan here
        local -r addr=&quot;${IP_ADDRS[$ip_i]#$NA}&quot;
        local -r dev=&quot;${vlan:-$iface}&quot;
        local bits=&quot;${IP_SBITSS[$ip_i]#$NA}&quot;

        [ &quot;$secad&quot; != &quot;$YES&quot; ] || bits=32
        oci_vcn_debug &quot;addr $addr del ns '$ns' dev $dev&quot;
        $IP $nscmd addr del $addr/$bits dev $dev || oci_vcn_err &quot;cannot remove IP address $addr/$bits from interface $dev&quot;
        oci_vcn_info &quot;removed IP address $addr from interface $dev&quot;
    fi
}

oci_vcn_ip_addr_add() {
    local -ir md_i=$1
    local -r mac=&quot;${MD_MACS[$md_i]}&quot;
    local -r addr=&quot;${MD_ADDRS[$md_i]}&quot;
    local ns=''
    local iface=''
    local -i nic_i
    local -i vltag

    # note that when adding an addr to a physical iface ip_i will be the index of the
    # addr, but when creating a vlan for addr ip_i will not be the vlan iface but its phys one
    local -i ip_i

    if [ -z &quot;$IS_VM&quot; ]; then
        # bm vnics' physical ifaces are identified by nic index
        nic_i=${MD_NIC_IS[$md_i]}
        [ $nic_i -lt ${#NIC_IP_IS[@]} ] || oci_vcn_err &quot;cannot find interface for NIC $nic_i&quot;
        ip_i=${NIC_IP_IS[$nic_i]}
        iface=&quot;${IP_IFACES[$ip_i]}&quot;
        vltag=${MD_VLTAGS[$md_i]}
    else
        # vm vnics' physical ifaces are identified by matching mac
        local found=''
        ip_i=0
        local ip_mac
        for ip_mac in &quot;${IP_MACS[@]}&quot;; do
            if [ &quot;$ip_mac&quot; = &quot;$mac&quot; ]; then
                found='t'
                break
            fi
            ip_i+=1
        done
        [ -n &quot;$found&quot; ] || oci_vcn_err &quot;cannot find interface matching VNIC MAC $mac&quot;
        iface=&quot;${IP_IFACES[$ip_i]}&quot;
        nic_i=${IP_NIC_IS[$ip_i]}
        vltag=0
    fi

    # check that there is no current addr on iface
    if [ -n &quot;$IS_VM&quot; ] || [ &quot;${MD_VLTAGS[$md_i]}&quot; = &quot;0&quot; ]; then # putting addr directly on iface
        local -r ip_addr=&quot;${IP_ADDRS[$ip_i]#$NA}&quot;
        [ -z &quot;$ip_addr&quot; ] || oci_vcn_err &quot;IP address $ip_addr already added on interface $iface&quot;
    fi

    # make sure physical iface/nic is up
    if [ &quot;${IP_STATES[$ip_i]}&quot; != &quot;UP&quot; ]; then
        $IP link set dev $iface up || oci_vcn_err &quot;cannot set interface $iface up&quot;
    fi

    # create namespace if requested
    local ns=''
    if [ -n &quot;$USE_NS&quot; ]; then
        ns=$(oci_vcn_ip_ns_create $nic_i $vltag) || exit $?
        # if working on a physical iface we need to set its namespace so that any
        # vlan created subsequently will know how to find it
        [ $vltag -ne 0 ] || IP_NSS[$ip_i]=&quot;$ns&quot;
    fi

    # add addr to iface (possibly creating vlan)
    local dev
    dev=$(oci_vcn_ip_addr_add_iface $md_i $ip_i $ns) || exit $?

    # setup routes
    oci_vcn_ip_routing_add $md_i $nic_i $dev $ns

    # if namespace then wait for changes and start services
    if [ -n &quot;$ns&quot; ]; then
        sleep 1 # namespace changes seem to take time
        oci_vcn_ip_ns_svcs_start $ns
    fi
}

oci_vcn_ip_sec_addr_add() {
    local -ir iface_ip_i=$1
    local -r addr=$2
    local -r iface=&quot;${IP_IFACES[$iface_ip_i]}&quot;
    local -r vlan=&quot;${IP_VLANS[$iface_ip_i]#$NA}&quot;
    local -r dev=&quot;${vlan:-$iface}&quot;
    local -r ns=&quot;${IP_NSS[$iface_ip_i]#$NA}&quot;
    local nscmd=''
    local nsinfo=''

    # config routing
    oci_vcn_ip_routing_sec_addr_add $iface_ip_i $addr

    # config the addr on the iface
    if [ -n &quot;$ns&quot; ]; then
        nscmd=&quot;netns exec $ns $IP&quot;
        nsinfo=&quot; in namespace $ns&quot;
    fi
    oci_vcn_info &quot;adding secondary IP address $addr to interface (or VLAN) $dev$nsinfo&quot;
    $IP $nscmd addr add $addr/32 dev $dev || oci_vcn_err &quot;cannot add secondary IP address $addr on interface $dev$nsinfo&quot;
}

oci_vcn_ip_sec_addr_del() {
    local -ir ip_i=$1
    local -r deconfig_all=$2
    local -r addr=${IP_ADDRS[$ip_i]}
    local -r iface=${IP_IFACES[$ip_i]}
    local -r vlan=&quot;${IP_VLANS[$ip_i]#$NA}&quot;
    local -r dev=&quot;${vlan:-$iface}&quot;
    local -r ns=&quot;${IP_NSS[$ip_i]#$NA}&quot;
    local nscmd=''
    local nsinfo=''

    [ &quot;${IP_SECADS[$ip_i]}&quot; = &quot;$YES&quot; ] || oci_vcn_err &quot;not a secondary IP address: $addr&quot;

    # remove the addr on the iface (see comments in add)
    # no need if deconfig all and on a vlan or in namespace
    if [ -z &quot;$deconfig_all&quot; ] || ([ -z &quot;$vlan&quot; ] &amp;&amp; [ -z &quot;$ns&quot; ]); then
        if [ -z &quot;$deconfig_all&quot; ] &amp;&amp; [ -n &quot;$ns&quot; ]; then
            nscmd=&quot;netns exec $ns $IP&quot;
            nsinfo=&quot; in namespace $ns&quot;
        fi

        oci_vcn_info &quot;removing secondary IP address $addr from interface (or VLAN) $dev$nsinfo&quot;
        $IP $nscmd addr del $addr/32 dev $dev || oci_vcn_err &quot;cannot remove IP address $addr on interface $dev&quot;
    fi

    # remove the routing (see comments in add)
    oci_vcn_ip_routing_sec_addr_del $ip_i $addr
}

oci_vcn_sec_addr_is_provisioned() {
    local -r find_addr=$1
    local -r find_vnic=$2
    local -i i
    local found=''

    for i in $(seq 0 $((${#SEC_ADDRS[@]} - 1))); do
        local addr=${SEC_ADDRS[$i]}
        local vnic=${SEC_VNICS[$i]}
        if [ &quot;$find_addr&quot; = &quot;$addr&quot; ] &amp;&amp; [ &quot;$find_vnic&quot; = &quot;$vnic&quot; ]; then
            found='t'
            break
        fi
    done
    echo &quot;$found&quot;
}

oci_vcn_ip_addr_del() {
    local -ir ip_i=$1
    local -r ns=&quot;${IP_NSS[$ip_i]#$NA}&quot;
    local -r secad=&quot;${IP_SECADS[$ip_i]#$NA}&quot;

    [ $ip_i -ne 0 ] || oci_vcn_err &quot;cannot remove primary VNIC&quot;

    if [ &quot;$secad&quot; != &quot;$YES&quot; ]; then
        if [ -n &quot;$ns&quot; ]; then
            # stop services in namespace
            oci_vcn_ip_ns_svcs_stop $ns
        fi

        # remove routing
        oci_vcn_ip_routing_del $ip_i
    fi

    # remove addr
    oci_vcn_ip_addr_del_iface $ip_i

    if [ &quot;$secad&quot; != &quot;$YES&quot; ] &amp;&amp; [ -n &quot;$ns&quot; ]; then
        # delete namespace
        oci_vcn_ip_ns_del $ns
        sleep 1 # namespace changes seem to take time
    fi
}

oci_vcn_ip_ifaces_read() {
    local -r ns=&quot;$1&quot;
    local nscmd=''
    local -a iface_datas

    if [ -n &quot;$ns&quot; ]; then # change ip command to use namespace
        nscmd=&quot;netns exec $ns $IP&quot;
    fi

    # read the interfaces in namespace (if any)
    # mapfile will create array with each line an element
    mapfile -t iface_datas &lt; &lt;($IP $nscmd addr show | awk -f $IFACE_AWK_SCRIPT) || oci_vcn_err &quot;cannot read IP addresses&quot;
    if [ ${#iface_datas[@]} -eq 0 ]; then
        # if reading physical ifaces, must be at least 1
        [ -n &quot;$ns&quot; ] || oci_vcn_err &quot;cannot locate interfaces&quot;
        # empty namespace: probably result of a VM VNIC delete
        # note empty namespaces do not survive reboot
        $IP netns del $ns || oci_vcn_err &quot;cannot delete empty namespace $ns&quot;
        oci_vcn_warn &quot;deleted empty namespace $ns&quot;
    else
        local -r nsna=&quot;${ns:-$NA}&quot;
        local -i ip_i=${#IP_MACS[@]} # continue from previous ns (if any)
        local line
        for line in &quot;${iface_datas[@]}&quot;; do
            # line items are in order printed by awk script print
            # note that $NA is used to mean null (i.e. not set)
            oci_vcn_debug &quot;iface line: $line&quot;
            local -a iface_data=($line)
            local iface=&quot;${iface_data[1]}&quot;
            # filter out virtual interfaces if VM (assume created by user for other purpose)
            if [ -z &quot;$IS_VM&quot; ] || [ -z &quot;${VIRTUAL_IFACES[$iface]}&quot; ]; then
                local mac=&quot;${iface_data[0]}&quot;
                IP_MACS+=(&quot;$mac&quot;)
                IP_NSS+=(&quot;$nsna&quot;)
                IP_IFACES+=(&quot;$iface&quot;)
                IP_ADDRS+=(&quot;${iface_data[2]}&quot;)
                IP_SBITSS+=(&quot;${iface_data[3]}&quot;)
                IP_STATES+=(&quot;${iface_data[4]}&quot;)
                IP_VLANS+=(&quot;${iface_data[5]}&quot;)
                IP_VLTAGS+=(&quot;${iface_data[6]}&quot;)
                local secad=&quot;${iface_data[7]}&quot;
                IP_SECADS+=(&quot;$secad&quot;)
                [ &quot;$secad&quot; = &quot;$YES&quot; ] || IP_I_BY_MAC[&quot;$mac&quot;]=$ip_i # primary addrs only
                ip_i+=1
            fi
        done
    fi
}

oci_vcn_ip_read() {
    IP_I_BY_MAC=()
    IP_MACS=()
    IP_NSS=()
    IP_IFACES=()
    IP_ADDRS=()
    IP_SADDRS=()
    IP_SBITSS=()
    IP_VIRTRTS=()
    IP_STATES=()
    IP_VLANS=()
    IP_VLTAGS=()
    IP_SECADS=()
    IP_SRCS=()
    IP_NIC_IS=()
    NIC_IP_IS=()
    NIC_I_BY_PHYS_IP_I=()

    # read the non-namespace ifaces and any addrs on them
    oci_vcn_ip_ifaces_read
    # read ifaces in all the namespaces (if any), note some os's don't support netns
    mapfile -t nss &lt; &lt;($IP netns 2&gt;/dev/null)
    local ns
    for ns in &quot;${nss[@]}&quot;; do
        oci_vcn_ip_ifaces_read $ns
    done

    # set vltag 0 (for phys ifaces) and read os routes for all ifaces
    local -i ip_i
    for ip_i in $(seq 0 $((${#IP_MACS[@]} - 1))); do
        # any iface w/o vltag has tag 0
        [ -n &quot;${IP_VLTAGS[$ip_i]#$NA}&quot; ] || IP_VLTAGS[$ip_i]=0
        oci_vcn_ip_routes_read $ip_i
    done

    # find the &quot;physical&quot; iface indices: vltag 0 and not secondary addr
    # note vm ifaces are considered physical
    # these may not be in nic index order due to inclusion in namespaces (see next)
    local -r tmpfile=$(mktemp /tmp/oci_vcn_ifaces.XXXXX)
    local -A ip_i_by_phys_iface
    for ip_i in $(seq 0 $((${#IP_MACS[@]} - 1))); do
        if [ ${IP_VLTAGS[$ip_i]} -eq 0 ] &amp;&amp; [ &quot;${IP_SECADS[$ip_i]}&quot; != &quot;$YES&quot; ]; then
            # physical iface/nic
            local iface=${IP_IFACES[$ip_i]}
            ip_i_by_phys_iface[$iface]=$ip_i
            echo &quot;$iface&quot; &gt;&gt; &quot;$tmpfile&quot;
        fi
        NIC_I_BY_PHYS_IP_I[$ip_i]=-1
    done

    # sort physical ifaces by first number (either at end or in middle) in iface name
    # this will provide the nic index
    local -i nic_i=0
    local iface
    for iface in $(cat &quot;$tmpfile&quot; | awk -- '{ match($1, /[0-9]+/); print substr($1, RSTART, RLENGTH), $1 }' | sort -n | cut -f 2 -d ' '); do
        local ip_i=${ip_i_by_phys_iface[$iface]}
        NIC_IP_IS+=($ip_i)
        NIC_I_BY_PHYS_IP_I[$ip_i]=$nic_i
        nic_i+=1
    done
    rm &quot;$tmpfile&quot;

    # for each iface (phys or vlan) get nic index
    for ip_i in $(seq 0 $((${#IP_MACS[@]} - 1))); do
        local iface=${IP_IFACES[$ip_i]}
        local -i phys_ip_i=${ip_i_by_phys_iface[$iface]}
        IP_NIC_IS[$ip_i]=${NIC_I_BY_PHYS_IP_I[$phys_ip_i]}
    done

    # fix up missing nic index for bms (see also oci_vcn_md_read): bms will be missing nic index metadata
    # if they were created before and have not had a vnic attached or detached since 8/23/17.
    # if there is a secondary vnic created and configured (before 8/23/17) we can tell it is a bm
    # because there will either be configured vlans or more vnics than physical ifaces.
    # note that gen 2 shapes are post 8/23/17 and, hence, will have nic indices already set.
    # a missing nic index for an old bm will not matter if there are no vnics to configure.
    if [ ${#MD_NIC_IS[@]} -eq 0 ] &amp;&amp; [ ${#NIC_IP_IS[@]} -eq 1 ] &amp;&amp; \
        ([ ${#IP_MACS[@]} -gt 1 ] || [ ${#MD_MACS[@]} -gt 1 ]); then # configured or new secondaries
        local -i md_i
        for md_i in $(seq 0 $((${#MD_MACS[@]} - 1))); do
            MD_NIC_IS+=(0)
        done
        oci_vcn_info &quot;legacy BM instance detected&quot;
        IS_VM=''
    fi
}

oci_vcn_read() {
    # assumes md info is already read
    # reads ip configs and creates single array of all macs
    # (fixes vm interfaces if random mac)
    [ -n &quot;$IP&quot; ] || oci_vcn_err &quot;cannot find ip command&quot;
    local warn_ifaces=''
    local -i attempt
    for attempt in 1 2; do
        # initialize md/ip shared arrays
        MACS=(&quot;${MD_MACS[@]}&quot;)
        # read all of ip config info and see if it matches md info
        oci_vcn_ip_read
        MD_CONFIGS=()
        local -i md_i=0
        local mac
        for mac in &quot;${MD_MACS[@]}&quot;; do
            MD_CONFIGS[$md_i]=&quot;$NA&quot;
            local -i ip_i=${IP_I_BY_MAC[$mac]:--1}
            if [ $ip_i -lt 0 ]; then
                # if there is no corresponding iface mac: add
                # note ifaces with random macs will be detected below and this will be retried
                MD_CONFIGS[$md_i]=&quot;$ADD&quot;
            else
                local addr=&quot;${IP_ADDRS[$ip_i]#$NA}&quot;
                if [ -z &quot;$addr&quot; ]; then
                    # matching mac iface does not have address: add
                    # make sure it is not a (corrupted) vlan that had been configured previously
                    [ ${IP_VLTAGS[$ip_i]} -eq 0 ] || oci_vcn_err &quot;VLAN (with MAC $mac) configured but missing IP address (must manually fix)&quot;
                    MD_CONFIGS[$md_i]=&quot;$ADD&quot;
                fi
            fi
            md_i+=1
        done
        local -i ip_i=0
        IP_CONFIGS=()
        local retry=''
        warn_ifaces=''
        local -A new_macs=() # for deduping secondary addr macs
        for mac in &quot;${IP_MACS[@]}&quot;; do
            IP_CONFIGS[$ip_i]=&quot;$NA&quot;
            local addr=&quot;${IP_ADDRS[$ip_i]#$NA}&quot;
            # note that the primary vnic will be matched up (permanently)
            local -i md_i=${MD_I_BY_MAC[$mac]:--1}
            if [ $md_i -lt 0 ]; then
                # no metadata mac corresponding to ip mac
                local iface=&quot;${IP_IFACES[$ip_i]}&quot;
                if [ -n &quot;$addr&quot; ]; then
                    # addr is configured: should be deleted
                    # bm case (in vm case ifaces are auto-deleted when vnic is detached)
                    IP_CONFIGS[$ip_i]=&quot;$DELETE&quot;
                elif [ -z &quot;$IS_VM&quot; ]; then
                    # bm iface mac w/o addr and w/o md mac:
                    # skip if phys iface, else addr deleted w/o deleting vlan?
                    if [ ${IP_VLTAGS[$ip_i]} -ne 0 ]; then
                        IP_CONFIGS[$ip_i]=&quot;$DELETE&quot;
                        warn_ifaces=&quot;$warn_ifaces $iface&quot;
                    fi
                else
                    # vm iface mac w/o addr and w/o md mac: assume random mac
                    ([ $attempt -eq 1 ] &amp;&amp; [ &quot;${IP_STATES[$ip_i]}&quot; = 'DOWN' ]) || oci_vcn_err &quot;interface $iface with MAC $mac does not have corresponding metadata&quot;
                    # assume vm case 1st since less likely addr was deleted
                    # attempt mac fix by turning iface up, then retry
                    # this is probably an Intel driver problem
                    # could look at /sys/class/net/&lt;iface&gt;/addr_assign_type
                    $IP link set dev $iface up || oci_vcn_err &quot;cannot set interface $iface up&quot;
                    retry='t'
                fi
                if [ -z &quot;${new_macs[$mac]}&quot; ]; then
                    new_macs[$mac]='t'
                    MACS+=(&quot;$mac&quot;) # accumulate all unique macs
                fi
                # TODO else validate for consistency?: addr, vltag, subnet, virtrt
            elif [ &quot;${IP_SECADS[$ip_i]}&quot; = &quot;$YES&quot; ]; then
                local is_prov=$(oci_vcn_sec_addr_is_provisioned $addr &quot;${MD_VNICS[$md_i]}&quot;)
                if [ -z &quot;$is_prov&quot; ]; then
                    IP_CONFIGS[$ip_i]=&quot;$DELETE&quot;
                fi
            fi
            ip_i+=1
        done
        [ -n &quot;$retry&quot; ] || break
    done

    if [ -n &quot;$warn_ifaces&quot; ]; then
        oci_vcn_warn &quot;no VNIC (or MAC does not match) and no address, interfaces will be marked for delete:$warn_ifaces&quot;
    fi
}

oci_vcn_config_or_deconfig_sec_addrs() {
    local -r do_config=&quot;$1&quot; # config if not empty, else deconfig
    local found=''
    # vnics must be configured, whether config or deconfig secondary addrs
    local -i i
    for i in $(seq 0 $((${#SEC_ADDRS[@]} - 1))); do
        local addr=${SEC_ADDRS[$i]}
        local vnic=${SEC_VNICS[$i]}
        # find vnic's mac
        local mac=''
        local -i md_i
        for md_i in $(seq 0 $((${#MD_MACS[@]} - 1))); do
            if [ &quot;$vnic&quot; = &quot;${MD_VNICS[$md_i]}&quot; ]; then
                mac=&quot;${MD_MACS[$md_i]}&quot;
                break
            fi
        done
        [ -n &quot;$mac&quot; ] || oci_vcn_err &quot;cannot find VNIC for secondary IP address $addr on $vnic&quot;
        # find mac in ip config
        local -i iface_ip_i=-1
        local already_config=''
        local -i ip_i
        for ip_i in $(seq 0 $((${#IP_MACS[@]} - 1))); do
            if [ &quot;$mac&quot; = &quot;${IP_MACS[$ip_i]}&quot; ]; then # put on this iface if not already configured
                [ $iface_ip_i -ge 0 ] || iface_ip_i=$ip_i # 1st is interface (secondary addrs come after)
                if [ &quot;$addr&quot; = &quot;${IP_ADDRS[$ip_i]}&quot; ]; then # already configured
                    already_config='t'
                    break
                fi
            fi
        done
        [ $iface_ip_i -ge 0 ] || oci_vcn_err &quot;cannot find interface for secondary IP address $addr on $vnic&quot;
        if [ -n &quot;$do_config&quot; ] &amp;&amp; [ -z &quot;$already_config&quot; ]; then # configure
            oci_vcn_ip_sec_addr_add $iface_ip_i $addr
            found='t'
        elif [ -z &quot;$do_config&quot; ] &amp;&amp; [ -n &quot;$already_config&quot; ]; then # deconfigure
            # note this path is only if deconfiguring just the secondaries
            oci_vcn_ip_sec_addr_del $ip_i
            found='t'
        fi
    done
    echo &quot;$found&quot;
}

oci_vcn_config() {
    local found=''
    local mac
    local -A configed

    # fix up config: md will indicate adds, ip deletes
    local -i md_i
    for md_i in $(seq 0 $((${#MD_CONFIGS[@]} - 1))); do
        local config=&quot;${MD_CONFIGS[$md_i]#$NA}&quot;
        if [ &quot;$config&quot; = &quot;$ADD&quot; ]; then
            oci_vcn_info &quot;adding IP config for VNIC MAC ${MD_MACS[$md_i]} with id ${MD_VNICS[$md_i]}&quot;
            oci_vcn_ip_addr_add $md_i
            found='t'
        fi
    done
    local del_vmac=''
    local -i ip_i
    for ip_i in $(seq 0 $((${#IP_CONFIGS[@]} - 1))); do
        local config=&quot;${IP_CONFIGS[$ip_i]#$NA}&quot;
        if [ &quot;$config&quot; = &quot;$DELETE&quot; ]; then
            # del all pri addrs and sec addrs (unless its vlan is being deleted)
            local mac=&quot;${IP_MACS[$ip_i]}&quot;
            local secad=&quot;${IP_SECADS[$ip_i]#$NA}&quot;
            if [ &quot;$secad&quot; != &quot;$YES&quot; ] || [ &quot;$del_vmac&quot; != &quot;$mac&quot; ]; then
                local addr=&quot;${IP_ADDRS[$ip_i]}&quot;
                oci_vcn_info &quot;removing IP config of address $addr from MAC $mac&quot;
                oci_vcn_ip_addr_del $ip_i
                found='t'
                # keep track of last deleted vlan
                [ &quot;${IP_VLTAGS[$ip_i]}&quot; -eq 0 ] || del_vmac=$mac
            fi
        fi
    done

    # config secondary addrs, if any
    local sec_addrs_found=''
    if [ ${#SEC_ADDRS[@]} -gt 0 ]; then
        # reread config if there were changes so that secondaries are put in the correct place
        if [ -n &quot;$found&quot; ]; then
            sleep 2 # wait for newly created ifaces to settle
            oci_vcn_read
        fi
        sec_addrs_found=$(oci_vcn_config_or_deconfig_sec_addrs 't') || exit $?
    fi

    [ -n &quot;$found&quot; ] || [ -n &quot;$sec_addrs_found&quot; ] || oci_vcn_info &quot;no changes, IP configuration is up-to-date&quot;
}

oci_vcn_deconfig_all() {
    local -i ip_i=0
    local found=''
    local mac
    for mac in &quot;${IP_MACS[@]}&quot;; do
        local addr=&quot;${IP_ADDRS[$ip_i]#$NA}&quot;
        if [ -n &quot;$addr&quot; ]; then # ip is configured
            # note that primaries are encountered first
            if [ &quot;${IP_SECADS[$ip_i]}&quot; != &quot;$YES&quot; ]; then # primary addr
                if [ $ip_i -gt 0 ]; then # skip pri vnic, pri addr
                    local -i md_i=${MD_I_BY_MAC[$mac]:--1}
                    local missing=&quot; missing&quot;
                    local vnicmsg=''
                    if [ $md_i -ge 0 ]; then vnicmsg=&quot; with id ${MD_VNICS[$md_i]}&quot;; missing=&quot;&quot;; fi
                    oci_vcn_info &quot;removing IP config of address $addr for$missing VNIC MAC $mac$vnicmsg&quot;
                    oci_vcn_ip_addr_del $ip_i
                    found='t'
                fi
            else # secondary addr
                oci_vcn_ip_sec_addr_del $ip_i 't'
                found='t'
            fi
        fi
        ip_i+=1
    done
    if [ -z &quot;$found&quot; ]; then
        oci_vcn_info &quot;no changes, no IP configuration to delete&quot;
    fi
}

oci_vcn_show() {
    local -r fmt=&quot;%-6s %-15s %-15s %-5s %-15s %-10s %-3s %-10s %-5s %-11s %-5s %-17s %s\n&quot;
    printf &quot;$fmt&quot; CONFIG ADDR SPREFIX SBITS VIRTRT NS IND IFACE VLTAG VLAN STATE MAC VNIC
    local mac
    for mac in &quot;${MACS[@]}&quot;; do # all known macs
        local config=&quot;$NA&quot;
        local addr=&quot;$NA&quot;
        local nic_i=&quot;$NA&quot;
        local vltag=&quot;$NA&quot;
        local sprefix=&quot;$NA&quot;
        local sbits=&quot;$NA&quot;
        local virtrt=&quot;$NA&quot;
        local ns=&quot;$NA&quot;
        local iface=&quot;$NA&quot;
        local vlan=&quot;$NA&quot;
        local state=&quot;$NA&quot;
        local vnic=&quot;$NA&quot;
        local -i md_i=${MD_I_BY_MAC[$mac]:--1}
        if [ $md_i -ge 0 ]; then # in md: ADD, or no change depending on ip info
            config=&quot;${MD_CONFIGS[$md_i]}&quot;
            nic_i=&quot;${MD_NIC_IS[$md_i]:-$NA}&quot;
            addr=&quot;${MD_ADDRS[$md_i]}&quot;
            [ -n &quot;$IS_VM&quot; ] || vltag=&quot;${MD_VLTAGS[$md_i]}&quot; # not used in vms
            sprefix=&quot;${MD_SPREFIXS[$md_i]}&quot;
            sbits=&quot;${MD_SBITSS[$md_i]}&quot;
            virtrt=&quot;${MD_VIRTRTS[$md_i]}&quot;
            vnic=&quot;${MD_VNICS[$md_i]}&quot;
        fi
        # find the ip info on this mac, note that there could be none, one,
        # or multiple addrs if secondaries addrs exist (they will come after primary)
        local -i ip_i=${IP_I_BY_MAC[$mac]:--1} # index of primary addr, if any
        if [ $ip_i -ge 0 ]; then
            local -i pri_ip_i=$ip_i
            local secad=''
            while true; do
                secad=&quot;${IP_SECADS[$ip_i]#$NA}&quot;
                [ $pri_ip_i -eq $ip_i ] || [ -n &quot;$secad&quot; ] || break
                vlan=&quot;${IP_VLANS[$ip_i]:-$NA}&quot;
                iface=&quot;${IP_IFACES[$ip_i]}&quot;
                ns=&quot;${IP_NSS[$ip_i]}&quot;
                state=&quot;${IP_STATES[$ip_i]}&quot;
                local cfg=&quot;${IP_CONFIGS[$ip_i]#$NA}&quot;
                [ -z &quot;$cfg&quot; ] || config=&quot;$cfg&quot;
                if [ $md_i -lt 0 ]; then # not in md, fill with ip info
                    addr=&quot;${IP_ADDRS[$ip_i]}&quot;
                    sbits=&quot;${IP_SBITSS[$ip_i]}&quot;
                    virtrt=&quot;${IP_VIRTRTS[$ip_i]}&quot;
                    [ -n &quot;$IS_VM&quot; ] || vltag=&quot;${IP_VLTAGS[$ip_i]}&quot;
                elif [ -n &quot;$secad&quot; ]; then
                    addr=&quot;${IP_ADDRS[$ip_i]}&quot;
                fi
                local -i nic_phys=${NIC_I_BY_PHYS_IP_I[$ip_i]}
                [ -n &quot;$secad&quot; ] || [ $nic_phys -lt 0 ] || nic_i=$nic_phys # don't show if sec addr
                if [ -z &quot;$secad&quot; ]; then
                    printf &quot;$fmt&quot; &quot;$config&quot; &quot;$addr&quot; &quot;$sprefix&quot; &quot;$sbits&quot; &quot;$virtrt&quot; &quot;$ns&quot; &quot;$nic_i&quot; &quot;$iface&quot; &quot;$vltag&quot; &quot;$vlan&quot; &quot;$state&quot; &quot;$mac&quot; &quot;$vnic&quot;
                else
                    printf &quot;$fmt&quot; &quot;$config&quot; &quot;$addr&quot; &quot;$NA&quot; &quot;$NA&quot; &quot;$NA&quot; &quot;$NA&quot; &quot;$NA&quot; &quot;$NA&quot; &quot;$NA&quot; &quot;$NA&quot; &quot;$NA&quot; &quot;$NA&quot; &quot;$NA&quot;
                fi
                ip_i+=1
            done
        else
            printf &quot;$fmt&quot; &quot;$config&quot; &quot;$addr&quot; &quot;$sprefix&quot; &quot;$sbits&quot; &quot;$virtrt&quot; &quot;$ns&quot; &quot;$nic_i&quot; &quot;$iface&quot; &quot;$vltag&quot; &quot;$vlan&quot; &quot;$state&quot; &quot;$mac&quot; &quot;$vnic&quot;
        fi
    done
}

oci_vcn_help() {
    cat &lt;&lt;EOF
NAME
    $THIS -- display and configure Oracle OCI Virtual Cloud Networks on instance

SYNOPSIS
    $THIS [-s] [-e &lt;IP address&gt; &lt;VNIC OCID&gt;]
    $THIS -c [-q] [-s] [-n [&lt;format&gt;] [-r]] [-e &lt;IP address&gt; &lt;VNIC OCID&gt; [-e ...]]
    $THIS -d [-q] [-s] [-e &lt;IP address&gt; &lt;VNIC OCID&gt;]

DESCRIPTION
    This shows the current OCI Virtual interface Cards provisioned in the cloud
    and configured on this instance. When a secondary VNIC is provisioned in OCI it must
    be explicitly configured on the instance using this script or similar commands.

    The first version of this command displays the currently provisioned VNICs and the
    current IP configuration for this instance. VNICs that are not yet configured are
    marked with '$ADD' and IP configurations that no longer have an associated VNIC
    are marked with '$DELETE'.

    The second version, with -c, configures VNICs that do not have an IP configuration
    and deletes the IP configurations of VNICs that are not currently provisioned.
    This puts the instance IP configuration in sync with current OCI provisioning.
    If one or more optional -e options are present the secondary IP addresses are
    configured on the same interfaces as the corresponding VNIC.

    The configuring interfaces can optionally be placed inside separate network
    namespaces. This is necessary when VNICs are in subnets (different VCNs) with
    overlapping address blocks and the network applications are not bound directly
    to interfaces. Network namespaces require applications to be launched in them
    explicitly (via 'ip netns exec &lt;ns&gt;') in order to establish association with
    the interface. When namespaces are not used, policy-based routing is configured
    to provide a default route to the secondary VNIC\'s virtual router (default
    gateway) when the VNIC\'s address is the source address.

    Bare Metal secondary VNICs are configured using VLANs (where there is no
    corresponding physical interface). These will look like 2 addition interfaces
    when showing IP links, with names like '$MACVLAN_FORMAT' for the MAC VLAN
    and '$VLAN_FORMAT' for the IP VLAN.

    The third version, -d, deletes all IP configuration for provisioned secondary VNICs
    as long as there is no -e option. If one or more optional -e options are present
    only the given secondary IP addresses are deconfigured and the remaining configuration
    is left as is.

    This script is made to be run periodically to pick up changes in VNIC provisioning
    (whether adding or deleting). Note that these IP configuration changes are not
    persistent, the script must, at a minimum, be run on each startup.

    -c          Add IP configuration for VNICs that are not configured and delete
                for VNICs that are no longer provisioned.
    -d          Deconfigure all VNICs (except the primary). If a -e option is also
                present only the secondary IP address(es) are deconfigured.
    -e &lt;IP address&gt; &lt;VNIC OCID&gt;
                Secondary private IP address to configure or deconfigure.
    -h          Print help.
    -n [&lt;format&gt;]
                When configuring, place interfaces in namespace identified by the given
                format. Format can include \$nic and \$vltag variables. The name
                defaults to '$DEF_NS_FORMAT_BM' for BMs and '$DEF_NS_FORMAT_VM' for VMs.
                When configuring multiple VNICs ensure the namespaces are unique.
    -q          Suppress information messages.
    -r          Start sshd in namespace (if -n is present)
    -s          Show information on all provisioning and interface configuration.
                This is the default action if no options are given.
                Columns:
                    CONFIG  '$ADD' indicates missing IP config, '$DELETE' missing VNIC
                    ADDR    IP address
                    SPREFIX subnet CIDR prefix
                    SBITS   subnet mask bits
                    VIRTRT  virutal router IP address
                    NS      namespace (if any)
                    IND     interface index (if BM)
                    IFACE   interface (underlying physical if VLAN is also set)
                    VLTAG   VLAN tag (if BM)
                    VLAN    IP virtual LAN (if any)
                    STATE   state of interface
                    MAC     MAC address
                    VNIC    VNIC object identifier
    -v          Verbose information messages.

EXAMPLES
    $THIS
        Show all provisioned VNICs and configured IP addresses.
    $THIS -c
        Set configuration without a namespace.
    $THIS -c -n ''
        Set configuration using a namespace with the default format.
    $THIS -c -n 'myns\$vltag'
        Set configuration using a namespace with format 'myns\$vltag'.

SEE ALSO:
    OCI networking overview including route tables and security lists:
        https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/overview.htm
    Note: secondary VNIC in different VCN not handled, requires manually adding default route:
        ip route add &lt;VCN2 CIDR&gt; via &lt;VCN2 sec VNIC subnet virt router ip&gt; dev &lt;VCN2 sec VNIC ifname&gt;
EOF
}

# TODO secondary private IPs in metadata

declare show=''
declare config=''
declare deconfig=''
declare os_ver=&quot;$OS_ID-$OS_VERSION&quot;
declare os_maj_ver=&quot;$OS_ID-$OS_MAJ_VERSION&quot;
while [ $# -ge 1 ]; do
    declare opt=&quot;$1&quot;
    shift
    case $opt in
        -c) config='t';;
        -d) deconfig='t';;
        -e) if [ $# -lt 2 ]; then oci_vcn_err &quot;secondary private IP address option requires &lt;IP address&gt; &lt;VNIC OCID&gt;&quot;; fi
            SEC_ADDRS+=($1); shift
            SEC_VNICS+=($1); shift
            ;;
        -n) if [ &quot;$os_maj_ver&quot; = &quot;ol-6&quot; ] || [ &quot;$os_maj_ver&quot; = &quot;centos-6&quot; ]; then
                oci_vcn_err &quot;namespaces not supported on this os version ($os_ver)&quot;
            fi
            if [ $# -ge 1 ] &amp;&amp; ! [[ &quot;$1&quot; =~ ^\- ]]; then
                [ -z &quot;$1&quot; ] || NS_FORMAT=&quot;$1&quot;
                shift
            fi
            USE_NS='t';;
        -r) START_SSHD='t'
            [ -n &quot;$SSHD&quot; ] || oci_vcn_err &quot;missing sshd command&quot;;;
        -s) show='t';;
        -h) oci_vcn_help; exit 0;;
        -q) if [ -n &quot;$DEBUG&quot; ]; then oci_vcn_err &quot;cannot specify quiet with verbose&quot;; fi
            QUIET='t';;
        -v) if [ -n &quot;$QUIET&quot; ]; then oci_vcn_err &quot;cannot specify verbose with quiet&quot;; fi
            DEBUG='t';;
        -*) oci_vcn_err &quot;unknown option $opt&quot;;;
    esac
done

[ -z &quot;$START_SSHD&quot; ] || [ -n &quot;$USE_NS&quot; ] || oci_vcn_err &quot;cannot start sshd if namespace is not created&quot;

[ $EUID -eq 0 ] || oci_vcn_err &quot;must be run as root&quot;

# read all metadata and ip config
oci_vcn_md_read
oci_vcn_read

# process options
if [ -n &quot;$config&quot; ]; then
    [ -z &quot;$deconfig&quot; ] || oci_vcn_err &quot;conflicting options&quot;
    oci_vcn_config
    [ -z &quot;$show&quot; ] || oci_vcn_read # reread if show
elif [ -n &quot;$deconfig&quot; ]; then
    if [ ${#SEC_ADDRS[@]} -gt 0 ]; then # just deconfig addrs
        oci_vcn_config_or_deconfig_sec_addrs
    else # deconfig all
        oci_vcn_deconfig_all
    fi
    [ -z &quot;$show&quot; ] || oci_vcn_read # reread if show
else
    show='t'
fi
[ -z &quot;$show&quot; ] || oci_vcn_show
" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">#!/usr/bin/env bash</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># Copyright (c) 2018, Oracle and/or its affiliates.</span></span>
<span class="line"><span style="color: #6A9955"># The Universal Permissive License (UPL), Version 1.0</span></span>
<span class="line"><span style="color: #6A9955">#</span></span>
<span class="line"><span style="color: #6A9955"># Oracle OCI Virtual Cloud Networks IP configuration script</span></span>
<span class="line"><span style="color: #6A9955">#</span></span>
<span class="line"><span style="color: #6A9955"># 2017-10-24 initial release</span></span>
<span class="line"><span style="color: #6A9955"># 2017-11-21 filter out VLANs if VM</span></span>
<span class="line"><span style="color: #6A9955"># 2017-11-21 inhibit namespaces for ubuntu 16</span></span>
<span class="line"><span style="color: #6A9955"># 2018-02-12 fix sshd typo in help</span></span>
<span class="line"><span style="color: #6A9955"># 2018-02-20 update copyright notice</span></span>
<span class="line"><span style="color: #6A9955"># 2018-03-21 fix to add src routing on primary VNIC when not using namespaces</span></span>
<span class="line"><span style="color: #6A9955"># 2018-04-05 add note on multiple VCNs</span></span>
<span class="line"><span style="color: #6A9955"># 2018-05-10 fix to delete config by deleting default route before deleting table, added -v option</span></span>
<span class="line"><span style="color: #6A9955"># 2018-05-22 fix to ignore interfaces enslaved to a master device</span></span>
<span class="line"><span style="color: #6A9955"># 2018-09-14 allow namespaces for Ubuntu 16 since problems with DHCP are fixed, and inhibit for all OL/Centos 6</span></span>
<span class="line"><span style="color: #6A9955"># 2018-09-19 fix os name and version setting for centos 6 images</span></span>
<span class="line"><span style="color: #6A9955"># 2018-09-19 fix ip addr parsing to remove MAC VLAN interfaces</span></span>
<span class="line"><span style="color: #6A9955"># 2018-10-25 fix secondary private ip src routing</span></span>
<span class="line"><span style="color: #6A9955"># 2018-10-31 fix misc routing setup, fix multiple ifaces on same subnet</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">THIS=$(</span><span style="color: #DCDCAA">basename</span><span style="color: #CE9178"> &quot;</span><span style="color: #9CDCFE">$0</span><span style="color: #CE9178">&quot;)</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">MD_URL=&#39;http://169.254.169.254/opc/v1/vnics/&#39;</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">NA=&#39;-&#39;</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">RTS_FILE=&#39;/etc/iproute2/rt_tables&#39;</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">RT_ID_MIN=</span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># in case lower ones are reserved</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">RT_ID_MAX=</span><span style="color: #B5CEA8">255</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">RT_FORMAT_BM=&#39;ort${nic}vl${vltag}&#39;</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">RT_FORMAT_VM=&#39;ort${nic}&#39;</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">DEF_NS_FORMAT_BM=&#39;ons${nic}vl${vltag}&#39;</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">DEF_NS_FORMAT_VM=&#39;ons${nic}&#39;</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">MACVLAN_FORMAT=&#39;${iface}.${vltag}&#39;</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># note awk script looks for this (max 15 chars)</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">VLAN_FORMAT=&#39;${iface}v${vltag}&#39;</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># (max 15 chars)</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">MTU=</span><span style="color: #B5CEA8">9000</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ADD=&#39;ADD&#39;</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">DELETE=&#39;DELETE&#39;</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">YES=&#39;YES&#39;</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">CURL=$(</span><span style="color: #DCDCAA">which</span><span style="color: #CE9178"> curl)</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">IP=$(</span><span style="color: #DCDCAA">which</span><span style="color: #CE9178"> ip)</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">SSHD=$(</span><span style="color: #DCDCAA">which</span><span style="color: #CE9178"> sshd)</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">MODPROBE=$(</span><span style="color: #DCDCAA">which</span><span style="color: #CE9178"> modprobe)</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">OS_RELEASE=&#39;/etc/os-release&#39;</span></span>
<span class="line"><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -f </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$OS_RELEASE</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">OS_ID=$(</span><span style="color: #DCDCAA">grep</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-ws</span><span style="color: #CE9178"> ID </span><span style="color: #9CDCFE">$OS_RELEASE</span><span style="color: #CE9178"> </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">cut</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-f</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">2</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-d</span><span style="color: #CE9178"> &#39;=&#39; </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">tr</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-d</span><span style="color: #CE9178"> &#39;&quot;&#39; </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">tr</span><span style="color: #CE9178"> &#39;[:upper:]&#39; &#39;[:lower:]&#39;)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">OS_VERSION=$(</span><span style="color: #DCDCAA">grep</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-ws</span><span style="color: #CE9178"> VERSION_ID </span><span style="color: #9CDCFE">$OS_RELEASE</span><span style="color: #CE9178"> </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">cut</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-f</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">2</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-d</span><span style="color: #CE9178"> &#39;=&#39; </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">tr</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-d</span><span style="color: #CE9178"> &#39;&quot;&#39;)</span></span>
<span class="line"><span style="color: #C586C0">else</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">OS_RELEASE_alt=&#39;/etc/redhat-release&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -f </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$OS_RELEASE_alt</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">OS_ID=$(</span><span style="color: #DCDCAA">cat</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$OS_RELEASE_alt</span><span style="color: #D4D4D4">|</span><span style="color: #DCDCAA">cut</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-f</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">1</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-d</span><span style="color: #CE9178"> &#39; &#39; </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">tr</span><span style="color: #CE9178"> &#39;[:upper:]&#39; &#39;[:lower:]&#39;)</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">OS_VERSION=$(</span><span style="color: #DCDCAA">cat</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$OS_RELEASE_alt</span><span style="color: #CE9178"> </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">cut</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-f</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">3</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-d</span><span style="color: #CE9178"> &#39; &#39;)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$OS_VERSION</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">OS_MAJ_VERSION=$(</span><span style="color: #DCDCAA">echo</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$OS_VERSION</span><span style="color: #CE9178"> </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">cut</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-f</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">1</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-d</span><span style="color: #CE9178"> &#39;.&#39;)</span></span>
<span class="line"><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">SYS_CLASS_NET=&#39;/sys/class/net&#39;</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-A</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">VIRTUAL_IFACES</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">IS_VM</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">MACS</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># all (unique) macs</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-A</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">MD_I_BY_MAC</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># index into arrays by MAC</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">MD_MACS</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">MD_ADDRS</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">MD_VLTAGS</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">MD_SCIDRS</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">MD_SPREFIXS</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">MD_SBITSS</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">MD_VIRTRTS</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">MD_VNICS</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">MD_NIC_IS</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># not set at all if vm</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">MD_CONFIGS</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># $ADD if vnic added</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-A</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">DUP_ADDRS</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># hash of addrs that appear more than once</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-A</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">DUP_SADDRS</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># hash of subnet addrs that appear more than once</span></span>
<span class="line"><span style="color: #6A9955"># items use $NA to mean null</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-A</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">IP_I_BY_MAC</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># index into arrays by MAC</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">IP_MACS</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># runs of dups if sec addrs</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">IP_NSS</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">IP_IFACES</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">IP_ADDRS</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">IP_SADDRS</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">IP_SBITSS</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">IP_VIRTRTS</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">IP_STATES</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">IP_VLANS</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">IP_VLTAGS</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># vltag (0 if phys iface)</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">IP_SECADS</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># set to $YES if secondary addr</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">IP_SRCS</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># set to $YES if src hint</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">IP_NIC_IS</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># nic index of iface</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">IP_CONFIGS</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># $DELETE if vnic deleted</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">NIC_IP_IS</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># index of physical iface for nic index</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-A</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">NIC_I_BY_PHYS_IP_I</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># nic index for physical iface ip_i</span></span>
<span class="line"><span style="color: #6A9955"># be sure to clear any IP_ arrays above in the read function</span></span>
<span class="line"><span style="color: #6A9955"># options:</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">QUIET</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">DEBUG</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">START_SSHD</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">USE_NS</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">NS_FORMAT</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">SEC_ADDRS</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">SEC_VNICS</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">IFACE_AWK_SCRIPT=&#39;/tmp/oci_vcn_iface.awk&#39;</span></span>
<span class="line"><span style="color: #DCDCAA">cat</span><span style="color: #D4D4D4"> &gt;</span><span style="color: #9CDCFE">$IFACE_AWK_SCRIPT</span><span style="color: #D4D4D4"> &lt;&lt;&#39;</span><span style="color: #D4D4D4">EOF</span><span style="color: #D4D4D4">&#39;</span></span>
<span class="line"><span style="color: #CE9178">function prtiface(mac, iface, addr, sbits, state, vlan, vltag, secad) {</span></span>
<span class="line"><span style="color: #CE9178">    if (iface != &quot;&quot;) printf &quot;%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n&quot;, mac, iface, addr, sbits, state, vlan, vltag, secad</span></span>
<span class="line"><span style="color: #CE9178">}</span></span>
<span class="line"><span style="color: #CE9178">BEGIN { iface = &quot;&quot;; addr = &quot;-&quot; }</span></span>
<span class="line"><span style="color: #CE9178">/^[0-9]/ {</span></span>
<span class="line"><span style="color: #CE9178">    # if not the first and prev was not a mac vlan then print previous (note print at end too)</span></span>
<span class="line"><span style="color: #CE9178">    if (addr == &quot;-&quot;) prtiface(mac, iface, addr, sbits, state, vlan, vltag, secad)</span></span>
<span class="line"><span style="color: #CE9178">    addr = &quot;-&quot;</span></span>
<span class="line"><span style="color: #CE9178">    sbits = &quot;-&quot;</span></span>
<span class="line"><span style="color: #CE9178">    state = &quot;-&quot;</span></span>
<span class="line"><span style="color: #CE9178">    macvlan = &quot;-&quot;</span></span>
<span class="line"><span style="color: #CE9178">    vlan = &quot;-&quot;</span></span>
<span class="line"><span style="color: #CE9178">    vltag = &quot;-&quot;</span></span>
<span class="line"><span style="color: #CE9178">    secad = &quot;-&quot;</span></span>
<span class="line"><span style="color: #CE9178">    if ($0 ~ /BROADCAST/ &amp;&amp; $0 !~ /UNKNOWN/ &amp;&amp; $0 !~ /NO-CARRIER/ &amp;&amp; $0 !~ /master /) {</span></span>
<span class="line"><span style="color: #CE9178">        i = index($2, &quot;@&quot;)</span></span>
<span class="line"><span style="color: #CE9178">        if (1 &lt; i) {</span></span>
<span class="line"><span style="color: #CE9178">            j = index($2, &quot;.&quot;)</span></span>
<span class="line"><span style="color: #CE9178">            if (j &lt; i) { # mac vlan (not used, no addrs)</span></span>
<span class="line"><span style="color: #CE9178">                macvlan = substr($2, 1, i - 1)</span></span>
<span class="line"><span style="color: #CE9178">                iface = substr($2, i + 1, length($2) - i - 1) # skip : at end</span></span>
<span class="line"><span style="color: #CE9178">                addr = &quot;&quot; # skip the mac vlan iface</span></span>
<span class="line"><span style="color: #CE9178">            } else { # vlan</span></span>
<span class="line"><span style="color: #CE9178">                vlan = substr($2, 1, i - 1)</span></span>
<span class="line"><span style="color: #CE9178">                # extract iface/vltag from macvlan</span></span>
<span class="line"><span style="color: #CE9178">                iface = substr($2, i + 1, j - i - 1)</span></span>
<span class="line"><span style="color: #CE9178">                vltag = substr($2, j + 1, length($2) - j - 1) # skip : at end</span></span>
<span class="line"><span style="color: #CE9178">            }</span></span>
<span class="line"><span style="color: #CE9178">        } else {</span></span>
<span class="line"><span style="color: #CE9178">            i = index($2, &quot;:&quot;)</span></span>
<span class="line"><span style="color: #CE9178">            if (i &lt;= 1) { print &quot;cannot find interface name&quot;; exit 1 }</span></span>
<span class="line"><span style="color: #CE9178">            iface = substr($2, 1, i - 1)</span></span>
<span class="line"><span style="color: #CE9178">        }</span></span>
<span class="line"><span style="color: #CE9178">        if ($0 ~ /LOWER_UP/) state = &quot;UP&quot;</span></span>
<span class="line"><span style="color: #CE9178">        else state = &quot;DOWN&quot;</span></span>
<span class="line"><span style="color: #CE9178">    } else iface = &quot;&quot;</span></span>
<span class="line"><span style="color: #CE9178">    next</span></span>
<span class="line"><span style="color: #CE9178">}</span></span>
<span class="line"><span style="color: #CE9178">/ link\/ether / { mac = tolower($2) }</span></span>
<span class="line"><span style="color: #CE9178">/ inet [0-9]/ {</span></span>
<span class="line"><span style="color: #CE9178">    i = index($2, &quot;/&quot;)</span></span>
<span class="line"><span style="color: #CE9178">    if (i &lt;= 1) { print &quot;cannot find interface inet address&quot;; exit 1 }</span></span>
<span class="line"><span style="color: #CE9178">    if (addr != &quot;-&quot;) secad = &quot;YES&quot;</span></span>
<span class="line"><span style="color: #CE9178">    addr = substr($2, 0, i - 1)</span></span>
<span class="line"><span style="color: #CE9178">    sbits = substr($2, i + 1, length($2) - i)</span></span>
<span class="line"><span style="color: #CE9178">    prtiface(mac, iface, addr, sbits, state, vlan, vltag, secad)</span></span>
<span class="line"><span style="color: #CE9178">}</span></span>
<span class="line"><span style="color: #CE9178">END { if (addr == &quot;-&quot;) prtiface(mac, iface, addr, sbits, state, vlan, vltag, secad) }</span></span>
<span class="line"><span style="color: #D4D4D4">EOF</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">echo</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;Error: </span><span style="color: #9CDCFE">$1</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> &gt;&amp;2</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">exit</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">1</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_warn</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">echo</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;Warning: </span><span style="color: #9CDCFE">$1</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> &gt;&amp;2</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_info</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$QUIET</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #DCDCAA">echo</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;Info: </span><span style="color: #9CDCFE">$1</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> &gt;&amp;2</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_debug</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    [ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$DEBUG</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #DCDCAA">echo</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;Debug: </span><span style="color: #9CDCFE">$1</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> &gt;&amp;2</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_virtual_ifaces_read</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">VIRTUAL_IFACES</span><span style="color: #D4D4D4">=()</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">iface</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">iface</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">ls</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$SYS_CLASS_NET</span><span style="color: #CE9178">)</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">ls</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-l</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$SYS_CLASS_NET</span><span style="color: #CE9178">/</span><span style="color: #9CDCFE">$iface</span><span style="color: #D4D4D4"> | </span><span style="color: #DCDCAA">grep</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-wq</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">virtual</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">VIRTUAL_IFACES</span><span style="color: #D4D4D4">[</span><span style="color: #9CDCFE">$iface</span><span style="color: #D4D4D4">]=</span><span style="color: #CE9178">&#39;t&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">done</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_md_read</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># sets all MD data arrays and their index I_BY_MAC</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">tmpfile=$(</span><span style="color: #DCDCAA">mktemp</span><span style="color: #CE9178"> /tmp/oci_vcn_md.XXXXX)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># MD notes:</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># vnic order: primary first, then time created (and therefore vltag/nic)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># BM notes: (1) may be interleaved wrt nic index (i.e. all nic 0 not guaranteed before all nic 1)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># (2) nicIndex was supported starting around 8/23/17, but will not appear on previously</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># launched instances unless refreshed by a vnic attach or detach after that date</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># parse: force json fields on separate lines</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># WARNING: assumes no string values with commas or double quotes</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># WARNING: assumes no sub-objects with identical field names</span></span>
<span class="line"><span style="color: #D4D4D4">    [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$CURL</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot find curl command&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">$CURL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-s</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$MD_URL</span><span style="color: #D4D4D4"> | </span><span style="color: #DCDCAA">tr</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">,</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;\n&#39;</span><span style="color: #D4D4D4"> &gt;</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$tmpfile</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot read metadata&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">MD_MACS</span><span style="color: #D4D4D4">=(</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">grep</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-w</span><span style="color: #CE9178"> macAddr &quot;</span><span style="color: #9CDCFE">$tmpfile</span><span style="color: #CE9178">&quot; </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">cut</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-f</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">4</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-d</span><span style="color: #CE9178"> &#39;&quot;&#39;)</span><span style="color: #D4D4D4">) || </span><span style="color: #DCDCAA">exit</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">$?</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># string</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">i</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">i</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">seq</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">0</span><span style="color: #CE9178"> $((${</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">MD_MACS</span><span style="color: #CE9178">[@]} </span><span style="color: #D4D4D4">-</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">1</span><span style="color: #CE9178">)))</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">MD_MACS</span><span style="color: #D4D4D4">[</span><span style="color: #9CDCFE">$i</span><span style="color: #D4D4D4">]=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">MD_MACS</span><span style="color: #CE9178">[$i],,}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">done</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">MD_ADDRS</span><span style="color: #D4D4D4">=(</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">grep</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-w</span><span style="color: #CE9178"> privateIp &quot;</span><span style="color: #9CDCFE">$tmpfile</span><span style="color: #CE9178">&quot; </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">cut</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-f</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">4</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-d</span><span style="color: #CE9178"> &#39;&quot;&#39;)</span><span style="color: #D4D4D4">) </span><span style="color: #6A9955"># string</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">MD_VLTAGS</span><span style="color: #D4D4D4">=(</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">grep</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-w</span><span style="color: #CE9178"> vlanTag &quot;</span><span style="color: #9CDCFE">$tmpfile</span><span style="color: #CE9178">&quot; </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">cut</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-f</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">2</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-d</span><span style="color: #CE9178"> &#39;:&#39; </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">tr</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-d</span><span style="color: #CE9178"> &#39; &#39;)</span><span style="color: #D4D4D4">) </span><span style="color: #6A9955"># integer</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">MD_VIRTRTS</span><span style="color: #D4D4D4">=(</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">grep</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-w</span><span style="color: #CE9178"> virtualRouterIp &quot;</span><span style="color: #9CDCFE">$tmpfile</span><span style="color: #CE9178">&quot; </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">cut</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-f</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">4</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-d</span><span style="color: #CE9178"> &#39;&quot;&#39;)</span><span style="color: #D4D4D4">) </span><span style="color: #6A9955"># string</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">s</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">s</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">grep</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-w</span><span style="color: #CE9178"> subnetCidrBlock &quot;</span><span style="color: #9CDCFE">$tmpfile</span><span style="color: #CE9178">&quot; </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">cut</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-f</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">4</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-d</span><span style="color: #CE9178"> &#39;&quot;&#39;)</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># string</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">MD_SCIDRS</span><span style="color: #D4D4D4">+=(${</span><span style="color: #9CDCFE">s</span><span style="color: #D4D4D4">})</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">MD_SPREFIXS</span><span style="color: #D4D4D4">+=(${</span><span style="color: #9CDCFE">s</span><span style="color: #D4D4D4">%/*})</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">MD_SBITSS</span><span style="color: #D4D4D4">+=(${</span><span style="color: #9CDCFE">s</span><span style="color: #D4D4D4">#*/})</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">done</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">MD_VNICS</span><span style="color: #D4D4D4">=(</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">grep</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-w</span><span style="color: #CE9178"> vnicId &quot;</span><span style="color: #9CDCFE">$tmpfile</span><span style="color: #CE9178">&quot; </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">cut</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-f</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">4</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-d</span><span style="color: #CE9178"> &#39;&quot;&#39;)</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">MD_NIC_IS</span><span style="color: #D4D4D4">=(</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">grep</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-w</span><span style="color: #CE9178"> nicIndex &quot;</span><span style="color: #9CDCFE">$tmpfile</span><span style="color: #CE9178">&quot; </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">cut</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-f</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">2</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-d</span><span style="color: #CE9178"> &#39;:&#39; </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">tr</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-d</span><span style="color: #CE9178"> &#39; &#39;)</span><span style="color: #D4D4D4">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># do some validity checks on md data</span></span>
<span class="line"><span style="color: #D4D4D4">    [ ${#</span><span style="color: #9CDCFE">MD_MACS</span><span style="color: #D4D4D4">[@]} -eq ${#</span><span style="color: #9CDCFE">MD_ADDRS</span><span style="color: #D4D4D4">[@]} ] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;invalid metadata: MAC or IP addresses are missing&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    [ ${#</span><span style="color: #9CDCFE">MD_MACS</span><span style="color: #D4D4D4">[@]} -eq ${#</span><span style="color: #9CDCFE">MD_VLTAGS</span><span style="color: #D4D4D4">[@]} ] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;invalid metadata: MAC or VLAN tags are missing&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    [ ${#</span><span style="color: #9CDCFE">MD_MACS</span><span style="color: #D4D4D4">[@]} -eq ${#</span><span style="color: #9CDCFE">MD_VIRTRTS</span><span style="color: #D4D4D4">[@]} ] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;invalid metadata: MAC or virtual router addresses are missing&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    [ ${#</span><span style="color: #9CDCFE">MD_MACS</span><span style="color: #D4D4D4">[@]} -eq ${#</span><span style="color: #9CDCFE">MD_SPREFIXS</span><span style="color: #D4D4D4">[@]} ] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;invalid metadata: MAC or subnets are missing&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    [ ${#</span><span style="color: #9CDCFE">MD_MACS</span><span style="color: #D4D4D4">[@]} -eq ${#</span><span style="color: #9CDCFE">MD_VNICS</span><span style="color: #D4D4D4">[@]} ] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;invalid metadata: MAC or VNIC ids are missing&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">i</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">seq</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">0</span><span style="color: #CE9178"> $((${</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">MD_MACS</span><span style="color: #CE9178">[@]} </span><span style="color: #D4D4D4">-</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">1</span><span style="color: #CE9178">)))</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">        [[ ${</span><span style="color: #9CDCFE">MD_ADDRS</span><span style="color: #D4D4D4">[$i]} </span><span style="color: #D4D4D4">=~</span><span style="color: #D4D4D4"> ^[</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">-9]+</span><span style="color: #D7BA7D">\.</span><span style="color: #D4D4D4">[</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">-9]+</span><span style="color: #D7BA7D">\.</span><span style="color: #D4D4D4">[</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">-9]+</span><span style="color: #D7BA7D">\.</span><span style="color: #D4D4D4">[</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">-9]+$ ]] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;invalid metadata: address IP format incorrect: ${</span><span style="color: #9CDCFE">MD_ADDRS</span><span style="color: #CE9178">[$i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        [[ ${</span><span style="color: #9CDCFE">MD_VLTAGS</span><span style="color: #D4D4D4">[$i]} </span><span style="color: #D4D4D4">=~</span><span style="color: #D4D4D4"> ^[</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">-9]+$ ]] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;invalid metadata: VLAN tag incorrect: ${</span><span style="color: #9CDCFE">MD_VLTAGS</span><span style="color: #CE9178">[$i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        [[ ${</span><span style="color: #9CDCFE">MD_VIRTRTS</span><span style="color: #D4D4D4">[$i]} </span><span style="color: #D4D4D4">=~</span><span style="color: #D4D4D4"> ^[</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">-9]+</span><span style="color: #D7BA7D">\.</span><span style="color: #D4D4D4">[</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">-9]+</span><span style="color: #D7BA7D">\.</span><span style="color: #D4D4D4">[</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">-9]+</span><span style="color: #D7BA7D">\.</span><span style="color: #D4D4D4">[</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">-9]+$ ]] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;invalid metadata: virtual router address format incorrect: ${</span><span style="color: #9CDCFE">MD_VIRTRTS</span><span style="color: #CE9178">[$i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        [[ ${</span><span style="color: #9CDCFE">MD_SPREFIXS</span><span style="color: #D4D4D4">[$i]} </span><span style="color: #D4D4D4">=~</span><span style="color: #D4D4D4"> ^[</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">-9]+</span><span style="color: #D7BA7D">\.</span><span style="color: #D4D4D4">[</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">-9]+</span><span style="color: #D7BA7D">\.</span><span style="color: #D4D4D4">[</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">-9]+</span><span style="color: #D7BA7D">\.</span><span style="color: #D4D4D4">[</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">-9]+$ ]] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;invalid metadata: subnet prefix format incorrect: ${</span><span style="color: #9CDCFE">MD_SPREFIXS</span><span style="color: #CE9178">[$i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">done</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># set vm flag based on existence of nic index (see override in oci_vcn_ip_read)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># get the virtual interfaces if VM</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ ${#</span><span style="color: #9CDCFE">MD_NIC_IS</span><span style="color: #D4D4D4">[@]} -eq </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">IS_VM</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;t&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_virtual_ifaces_read</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># create reverse lookup</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">i</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;${</span><span style="color: #D4D4D4">!</span><span style="color: #9CDCFE">MD_MACS</span><span style="color: #CE9178">[@]}&quot;</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">MD_I_BY_MAC[$</span><span style="color: #D4D4D4">{MD_MACS[</span><span style="color: #9CDCFE">$i</span><span style="color: #D4D4D4">]}</span><span style="color: #DCDCAA">]</span><span style="color: #D4D4D4">=</span><span style="color: #9CDCFE">$i</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">done</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">rm</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$tmpfile</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># find the duplicate addrs, if any</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-A</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">addrs=</span><span style="color: #D4D4D4">()</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">addr</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">addr</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">MD_ADDRS</span><span style="color: #CE9178">[@]}&quot;</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">addrs</span><span style="color: #CE9178">[$addr]}&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">DUP_ADDRS</span><span style="color: #D4D4D4">[</span><span style="color: #9CDCFE">$addr</span><span style="color: #D4D4D4">]=</span><span style="color: #CE9178">&#39;t&#39;</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">addrs</span><span style="color: #D4D4D4">[</span><span style="color: #9CDCFE">$addr</span><span style="color: #D4D4D4">]=</span><span style="color: #CE9178">&#39;t&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">done</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># find the duplicate subnet addrs, if any</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-A</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">saddrs=</span><span style="color: #D4D4D4">()</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">addr</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">MD_SPREFIXS</span><span style="color: #CE9178">[@]}&quot;</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">saddrs</span><span style="color: #CE9178">[$addr]}&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">DUP_SADDRS</span><span style="color: #D4D4D4">[</span><span style="color: #9CDCFE">addr</span><span style="color: #D4D4D4">]=</span><span style="color: #CE9178">&#39;t&#39;</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">saddrs</span><span style="color: #D4D4D4">[</span><span style="color: #9CDCFE">addr</span><span style="color: #D4D4D4">]=</span><span style="color: #CE9178">&#39;t&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">done</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_ip_route_table_name</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">nic=</span><span style="color: #9CDCFE">$1</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># format looks for &quot;${nic}&quot;, note this is really $nic_i</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">vltag=</span><span style="color: #9CDCFE">$2</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">format</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$RT_FORMAT_VM</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$IS_VM</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #9CDCFE">format</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$RT_FORMAT_BM</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">eval</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">echo</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$format</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_ip_route_table_name_ip_i</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># use only when ip already setup</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ip_i=</span><span style="color: #9CDCFE">$1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">nic_i=</span><span style="color: #D4D4D4">${</span><span style="color: #9CDCFE">IP_NIC_IS</span><span style="color: #D4D4D4">[$ip_i]}</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">vltag=</span><span style="color: #D4D4D4">${</span><span style="color: #9CDCFE">IP_VLTAGS</span><span style="color: #D4D4D4">[$ip_i]}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">oci_vcn_ip_route_table_name</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$nic_i</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$vltag</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_ip_route_table_exists</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">rt_name=</span><span style="color: #9CDCFE">$1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">grep</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-qsw</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$RTS_FILE</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">echo</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$rt_name</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_ip_route_table_find_unused_id</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># read all the current route table id/name pairs</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># mapfile will create array with each line an element</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">lines</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">mapfile</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-t</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">lines</span><span style="color: #D4D4D4"> &lt; </span><span style="color: #CE9178">&lt;(</span><span style="color: #DCDCAA">cat</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$RTS_FILE</span><span style="color: #CE9178"> </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">grep</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-E</span><span style="color: #CE9178"> &#39;^[0-9]&#39; </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">tr</span><span style="color: #CE9178"> &#39;\t&#39; &#39; &#39; </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">tr</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-s</span><span style="color: #CE9178"> &#39; &#39; &#39; &#39;)</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot read route tables file </span><span style="color: #9CDCFE">$RTS_FILE</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">line</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-A</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">rt_by_id</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">line</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">lines</span><span style="color: #CE9178">[@]}&quot;</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">pair=</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">$line</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">id</span><span style="color: #D4D4D4">=${</span><span style="color: #9CDCFE">pair</span><span style="color: #D4D4D4">[0]}</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">name</span><span style="color: #D4D4D4">=${</span><span style="color: #9CDCFE">pair</span><span style="color: #D4D4D4">[1]}</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">rt_by_id</span><span style="color: #D4D4D4">[</span><span style="color: #9CDCFE">$id</span><span style="color: #D4D4D4">]=</span><span style="color: #9CDCFE">$name</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">done</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># find first id not used</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">unused=</span><span style="color: #B5CEA8">-1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">i</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">i</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">seq</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$RT_ID_MIN</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$RT_ID_MAX</span><span style="color: #CE9178">)</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -z </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">rt_by_id</span><span style="color: #CE9178">[$i]}&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">unused</span><span style="color: #D4D4D4">=</span><span style="color: #9CDCFE">$i</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">break</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">done</span></span>
<span class="line"><span style="color: #D4D4D4">    [ </span><span style="color: #9CDCFE">$unused</span><span style="color: #D4D4D4"> -ne </span><span style="color: #B5CEA8">-1</span><span style="color: #D4D4D4"> ] ||  </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot find unused id in route tables file </span><span style="color: #9CDCFE">$RTS_FILE</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">echo</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$unused</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_ip_route_table_create</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">nic_i=</span><span style="color: #9CDCFE">$1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">vltag=</span><span style="color: #9CDCFE">$2</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">skip_if_exists=</span><span style="color: #9CDCFE">$3</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">rt_name=$(</span><span style="color: #DCDCAA">oci_vcn_ip_route_table_name</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$nic_i</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$vltag</span><span style="color: #CE9178">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># Check if the route table exists</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">rt_exists</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">rt_exists</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">oci_vcn_ip_route_table_exists</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #CE9178">)</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">exit</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">$?</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$rt_exists</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># already exists</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$skip_if_exists</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #DCDCAA">oci_vcn_debug</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;create route table </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #CE9178"> already exists, skipping&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">return</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_warn</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;route table </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #CE9178"> already exists, reusing&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">else</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># create</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">rt_id</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">rt_id</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">oci_vcn_ip_route_table_find_unused_id</span><span style="color: #CE9178">)</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">exit</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">$?</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_debug</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;create route table </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #CE9178"> (</span><span style="color: #9CDCFE">$rt_id</span><span style="color: #CE9178">)&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">echo</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$rt_id</span><span style="color: #CE9178">    </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> &gt;&gt; </span><span style="color: #9CDCFE">$RTS_FILE</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">echo</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$rt_name</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_ip_route_table_del</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">rt_name=</span><span style="color: #9CDCFE">$1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">tmpfile=$(</span><span style="color: #DCDCAA">mktemp</span><span style="color: #CE9178"> /tmp/oci_vcn_rt_tables.XXXXX)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> ! </span><span style="color: #DCDCAA">grep</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-qsw</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$RTS_FILE</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_debug</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;rt </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #CE9178"> not in </span><span style="color: #9CDCFE">$RTS_FILE</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">return</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">oci_vcn_debug</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;rt </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #CE9178"> delete&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">cp</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-p</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$RTS_FILE</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$tmpfile</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># in case grep fails</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">grep</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-vw</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$RTS_FILE</span><span style="color: #D4D4D4"> &gt; </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$tmpfile</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">mv</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$tmpfile</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$RTS_FILE</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">echo</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;t&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_ip_routing_add</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">md_i=</span><span style="color: #9CDCFE">$1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">nic_i=</span><span style="color: #9CDCFE">$2</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">iface=</span><span style="color: #9CDCFE">$3</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ns=</span><span style="color: #9CDCFE">$4</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">skip_if_exists=</span><span style="color: #9CDCFE">$5</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">vltag=&quot;${</span><span style="color: #9CDCFE">MD_VLTAGS</span><span style="color: #CE9178">[$md_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">addr=&quot;${</span><span style="color: #9CDCFE">MD_ADDRS</span><span style="color: #CE9178">[$md_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">sprefix=&quot;${</span><span style="color: #9CDCFE">MD_SPREFIXS</span><span style="color: #CE9178">[$md_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">virtrt=&quot;${</span><span style="color: #9CDCFE">MD_VIRTRTS</span><span style="color: #CE9178">[$md_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">scidr=&quot;${</span><span style="color: #9CDCFE">MD_SCIDRS</span><span style="color: #CE9178">[$md_i]}&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># set a default route to the gateway/virtual router</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">nscmd=&quot;netns exec </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$IP</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># using a namespace: iface is assumed only one in namespace, so just set a</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># default route to the gateway in the main route table</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_debug</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;default route add&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$nscmd</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">route</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">add</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">default</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">via</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$virtrt</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot add namespace </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178"> default gateway </span><span style="color: #9CDCFE">$virtrt</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_info</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;added namespace </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178"> default route to gateway </span><span style="color: #9CDCFE">$virtrt</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">else</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># the default route (in main route table) already defined through primary vnic.</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># this adds a rule to lookup a route table for any packets sourced from addr</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># and then the route table has the default route for that addr.</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># this allows packets from protocol services that reply with src addr</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># set to route back out through the iface (prevents asymmetric routing).</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># check for dup addrs and subnet addrs</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">DUP_ADDRS</span><span style="color: #CE9178">[$addr]}&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #DCDCAA">oci_vcn_warn</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;IP address </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178"> is a duplicate, skipping creating source route rule&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">return</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">        [ -z </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">DUP_SADDRS</span><span style="color: #CE9178">[$sprefix]}&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #DCDCAA">oci_vcn_warn</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;duplicate subnet prefix </span><span style="color: #9CDCFE">$sprefix</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># create route table and add a default route via the gateway, and subnet route</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">rt_name</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">rt_name</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">oci_vcn_ip_route_table_create</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$nic_i</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$vltag</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$skip_if_exists</span><span style="color: #CE9178">)</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">exit</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">$?</span></span>
<span class="line"><span style="color: #D4D4D4">        [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$rt_name</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #C586C0">return</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_debug</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;route table add rules&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">route</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">add</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">default</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">via</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$virtrt</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">dev</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$iface</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">table</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot add default route via </span><span style="color: #9CDCFE">$virtrt</span><span style="color: #CE9178"> on </span><span style="color: #9CDCFE">$iface</span><span style="color: #CE9178"> to table </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">route</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">add</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$scidr</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">dev</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$iface</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">table</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot add subnet </span><span style="color: #9CDCFE">$scidr</span><span style="color: #CE9178"> route on </span><span style="color: #9CDCFE">$iface</span><span style="color: #CE9178"> to table </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># create source-based rule to use table</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_debug</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;src rule add&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">rule</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">add</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">from</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$addr</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">lookup</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot add rule from </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178"> use table </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_info</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;added rule for routing from </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178"> lookup </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #CE9178"> with default via </span><span style="color: #9CDCFE">$virtrt</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_ip_routing_del</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ip_i=</span><span style="color: #9CDCFE">$1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ns=&quot;${</span><span style="color: #9CDCFE">IP_NSS</span><span style="color: #CE9178">[$ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">iface=&quot;${</span><span style="color: #9CDCFE">IP_IFACES</span><span style="color: #CE9178">[$ip_i]}&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># for namespaces the subnet and default routes will be auto deleted with the namespace</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># delete rule</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">rt_name=$(</span><span style="color: #DCDCAA">oci_vcn_ip_route_table_name_ip_i</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$ip_i</span><span style="color: #CE9178">)</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">had_rule</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> rule | </span><span style="color: #DCDCAA">grep</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-qsw</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># rule(s) exists</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #6A9955"># note that there may be secondary private ips rules using the same table</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #DCDCAA">oci_vcn_debug</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;rules to table </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #CE9178"> delete&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">while</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> rule del lookup </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #D4D4D4"> 2&gt;/dev/null; </span><span style="color: #C586C0">do</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">true</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">done</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">had_rule</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;t&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># delete route table</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">had_table</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">had_table</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">oci_vcn_ip_route_table_del</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #CE9178">)</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">exit</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">$?</span></span>
<span class="line"><span style="color: #D4D4D4">        ([ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$had_rule</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] &amp;&amp; [ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$had_table</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]) || </span><span style="color: #DCDCAA">oci_vcn_info</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;removed routing on interface </span><span style="color: #9CDCFE">$iface</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_ip_routing_sec_addr_add</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">iface_ip_i=</span><span style="color: #9CDCFE">$1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">addr=</span><span style="color: #9CDCFE">$2</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ns=&quot;${</span><span style="color: #9CDCFE">IP_NSS</span><span style="color: #CE9178">[$iface_ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># need to add source rule so reuse the routing table from the primary private ip</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># not needed if in namespace</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># not needed if on pri iface (uses main route table for dest and default route)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] &amp;&amp; [ </span><span style="color: #9CDCFE">$iface_ip_i</span><span style="color: #D4D4D4"> -ne </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># create source-based rule to use iface&#39;s routing table</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">rt_name=$(</span><span style="color: #DCDCAA">oci_vcn_ip_route_table_name_ip_i</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$iface_ip_i</span><span style="color: #CE9178">)</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_debug</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;sec addr src rule add&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">rule</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">add</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">from</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$addr</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">lookup</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot add rule from secondary </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178"> use table </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_info</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;added rule for routing from secondary IP address </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178"> lookup </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_ip_routing_sec_addr_del</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ip_i=</span><span style="color: #9CDCFE">$1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">addr=</span><span style="color: #9CDCFE">$2</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ns=&quot;${</span><span style="color: #9CDCFE">IP_NSS</span><span style="color: #CE9178">[$ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># deconfig the routing (see comments in add)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] &amp;&amp; [ </span><span style="color: #9CDCFE">$ip_i</span><span style="color: #D4D4D4"> -ne </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">rule</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">del</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">from</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$addr</span><span style="color: #D4D4D4"> 2&gt;</span><span style="color: #CE9178">/dev/null</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># ok if already deleted</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_info</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;deleted rule for routing from secondary IP address </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_ip_routes_read</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955">#ip r list 192.168.1.0/24</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ip_i=</span><span style="color: #9CDCFE">$1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ns=&quot;${</span><span style="color: #9CDCFE">IP_NSS</span><span style="color: #CE9178">[$ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">iface=&quot;${</span><span style="color: #9CDCFE">IP_IFACES</span><span style="color: #CE9178">[$ip_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">nscmd</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">virtrt</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">nscmd</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;netns exec </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$IP</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">else</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># no namespace: check for route table</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">rt_name=$(</span><span style="color: #DCDCAA">oci_vcn_ip_route_table_name_ip_i</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$ip_i</span><span style="color: #CE9178">)</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">rt_exists</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">rt_exists</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">oci_vcn_ip_route_table_exists</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #CE9178">)</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">exit</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">$?</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$rt_exists</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># exists</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #6A9955"># check for rule</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> rule | </span><span style="color: #DCDCAA">grep</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-qsw</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># rule exists that uses route table</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #6A9955"># look for default route in table, note table may exist but be empty</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #6A9955"># &quot;default via 10.0.0.1 dev ens3&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">def_entry</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #9CDCFE">def_entry</span><span style="color: #D4D4D4">=(</span><span style="color: #CE9178">$(</span><span style="color: #9CDCFE">$IP</span><span style="color: #CE9178"> route show table </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #CE9178"> </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">grep</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-sw</span><span style="color: #CE9178"> ^default)</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">def_entry</span><span style="color: #CE9178">[2]}&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #9CDCFE">virtrt</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">def_entry</span><span style="color: #CE9178">[2]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #DCDCAA">oci_vcn_debug</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;default route: </span><span style="color: #9CDCFE">$virtrt</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">else</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># emtpy table: delete rule and table</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #9CDCFE">virtrt</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #DCDCAA">oci_vcn_ip_routing_del</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$ip_i</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">else</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># clean up route table since no rule uses it</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #DCDCAA">$(oci_vcn_ip_route_table_del</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$rt_name</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># read the routes</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">sprefix</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">sbits</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">src</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># mapfile will create array with each line an element</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">mapfile</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-t</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">routes</span><span style="color: #D4D4D4"> &lt; </span><span style="color: #CE9178">&lt;(</span><span style="color: #9CDCFE">$IP</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$nscmd</span><span style="color: #CE9178"> route </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">grep</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-w</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$iface</span><span style="color: #CE9178">)</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot read IP routes for interface </span><span style="color: #9CDCFE">$iface</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">line</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">line</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">routes</span><span style="color: #CE9178">[@]}&quot;</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">route=</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">$line</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">route</span><span style="color: #CE9178">[0]}&quot;</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&#39;default&#39;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #6A9955"># &quot;default via 10.0.0.1 dev ens3&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">virtrt</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">route</span><span style="color: #CE9178">[2]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #DCDCAA">oci_vcn_debug</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;default route via: </span><span style="color: #9CDCFE">$virtrt</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">elif</span><span style="color: #D4D4D4"> [ </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">route</span><span style="color: #CE9178">[0]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">169</span><span style="color: #CE9178">.}&quot;</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">route</span><span style="color: #CE9178">[0]}&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># not cavium route</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #6A9955"># &quot;10.0.0.0/24 dev ens3 proto kernel scope link src 10.0.0.2&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">i</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">i</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">seq</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">0</span><span style="color: #CE9178"> $((${</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">route</span><span style="color: #CE9178">[@]} </span><span style="color: #D4D4D4">-</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">1</span><span style="color: #CE9178">)))</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">x</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">route</span><span style="color: #CE9178">[$i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #9CDCFE">$i</span><span style="color: #D4D4D4"> -eq </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #9CDCFE">sprefix</span><span style="color: #D4D4D4">=${</span><span style="color: #9CDCFE">x</span><span style="color: #D4D4D4">%/*}</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #9CDCFE">sbits</span><span style="color: #D4D4D4">=${</span><span style="color: #9CDCFE">x</span><span style="color: #D4D4D4">#*/}</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$sprefix</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$sbits</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># not valid line</span></span>
<span class="line"><span style="color: #D4D4D4">                        </span><span style="color: #9CDCFE">sprefix</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                        </span><span style="color: #9CDCFE">sbits</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                        </span><span style="color: #C586C0">break</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #C586C0">else</span></span>
<span class="line"><span style="color: #D4D4D4">                        </span><span style="color: #DCDCAA">oci_vcn_debug</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;subnet route: </span><span style="color: #9CDCFE">$sprefix</span><span style="color: #CE9178">/</span><span style="color: #9CDCFE">$sbits</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">elif</span><span style="color: #D4D4D4"> [ </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$x</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&#39;src&#39;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">src</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$YES</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">done</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">done</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">IP_VIRTRTS</span><span style="color: #D4D4D4">[</span><span style="color: #9CDCFE">$ip_i</span><span style="color: #D4D4D4">]=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$virtrt</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">IP_SADDRS</span><span style="color: #D4D4D4">[</span><span style="color: #9CDCFE">$ip_i</span><span style="color: #D4D4D4">]=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$sprefix</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">IP_SBITSS</span><span style="color: #D4D4D4">[</span><span style="color: #9CDCFE">$ip_i</span><span style="color: #D4D4D4">]=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$sbits</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">IP_SRCS</span><span style="color: #D4D4D4">[</span><span style="color: #9CDCFE">$ip_i</span><span style="color: #D4D4D4">]=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$src</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_macvlan_name</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">iface=</span><span style="color: #9CDCFE">$1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">vltag=</span><span style="color: #9CDCFE">$2</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">eval</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">echo</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$MACVLAN_FORMAT</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_vlan_name</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">iface=</span><span style="color: #9CDCFE">$1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">vltag=</span><span style="color: #9CDCFE">$2</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">eval</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">echo</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$VLAN_FORMAT</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_ip_ns_name</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">nic=</span><span style="color: #9CDCFE">$1</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># format looks for &quot;${nic}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">vltag=</span><span style="color: #9CDCFE">$2</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$USE_NS</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] &amp;&amp; [ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NS_FORMAT</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$IS_VM</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">NS_FORMAT</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$DEF_NS_FORMAT_VM</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">else</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">NS_FORMAT</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$DEF_NS_FORMAT_BM</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">eval</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">echo</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NS_FORMAT</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_ip_ns_svcs_stop</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ns=</span><span style="color: #9CDCFE">$1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">pids</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">pids</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #9CDCFE">$IP</span><span style="color: #CE9178"> netns pids </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">)</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot get ids for processes in namespace </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$pids</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">kill</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-TERM</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$pids</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot terminate namespace </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178"> processes: </span><span style="color: #9CDCFE">$pids</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_info</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;terminated namespace </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178"> processes: </span><span style="color: #9CDCFE">$pids</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_ip_ns_svcs_start</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ns=</span><span style="color: #9CDCFE">$1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$START_SSHD</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># start SSH daemon</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">netns</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">exec</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$ns</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$SSHD</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot start ssh daemon&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_info</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;started namespace </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178"> ssh daemon&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_ip_ns_del</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ns=</span><span style="color: #9CDCFE">$1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># note also deletes vlans and routes</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">netns</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">del</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$ns</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot delete namespace </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">oci_vcn_info</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;deleted namespace </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_ip_ns_create</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">nic_i=</span><span style="color: #9CDCFE">$1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">vltag=</span><span style="color: #9CDCFE">$2</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$MODPROBE</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot find modprobe command&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">$MODPROBE</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">8021</span><span style="color: #CE9178">q</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;failed to load 8021q module&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ns</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">ns</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">oci_vcn_ip_ns_name</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$nic_i</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$vltag</span><span style="color: #CE9178">)</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">exit</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">$?</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">netns</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">add</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$ns</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot create namespace </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">oci_vcn_info</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;created namespace </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">echo</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_ip_addr_add_iface</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">md_i=</span><span style="color: #9CDCFE">$1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ip_i=</span><span style="color: #9CDCFE">$2</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># index of physical iface/nic</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ns=</span><span style="color: #9CDCFE">$3</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">iface</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_IFACES</span><span style="color: #CE9178">[$ip_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">physns=&quot;${</span><span style="color: #9CDCFE">IP_NSS</span><span style="color: #CE9178">[$ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">mac=&quot;${</span><span style="color: #9CDCFE">MD_MACS</span><span style="color: #CE9178">[$md_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">vltag=&quot;${</span><span style="color: #9CDCFE">MD_VLTAGS</span><span style="color: #CE9178">[$md_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">addr=&quot;${</span><span style="color: #9CDCFE">MD_ADDRS</span><span style="color: #CE9178">[$md_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">sbits=&quot;${</span><span style="color: #9CDCFE">MD_SBITSS</span><span style="color: #CE9178">[$md_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">vlan</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># must be adding to physical iface/nic</span></span>
<span class="line"><span style="color: #D4D4D4">    [ -z </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_VLANS</span><span style="color: #CE9178">[$ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot add IP address </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178"> to virtual interface ${</span><span style="color: #9CDCFE">IP_VLANS</span><span style="color: #CE9178">[$ip_i]}&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># create virtual interface if needed (bm cases)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">macvlan</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$IS_VM</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] &amp;&amp; [ </span><span style="color: #9CDCFE">$vltag</span><span style="color: #D4D4D4"> -ne </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># bm vnics need a virtual iface except for vltag=0</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># if physical iface/nic is in a namespace we must go there to create</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">physnscmd</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$physns</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">physnscmd</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;netns exec </span><span style="color: #9CDCFE">$physns</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$IP</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># create a mac vlan from physical iface/nic</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_debug</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;macvlan link add </span><span style="color: #9CDCFE">$macvlan</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">macvlan</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">oci_vcn_macvlan_name</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$iface</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$vltag</span><span style="color: #CE9178">)</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">exit</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">$?</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$physnscmd</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">link</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">add</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">link</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$iface</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">name</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$macvlan</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">address</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$mac</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">type</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">macvlan</span><span style="color: #D4D4D4"> </span><span style="color: #D7BA7D">\</span></span>
<span class="line"><span style="color: #D4D4D4">            || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot create MAC VLAN interface </span><span style="color: #9CDCFE">$macvlan</span><span style="color: #CE9178"> for MAC address </span><span style="color: #9CDCFE">$mac</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># if physical iface/nic is in a namespace pull out the created mac vlan</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$physns</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$physnscmd</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">link</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">set</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$macvlan</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">netns</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">1</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># create an ip vlan on top of the mac vlan</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_debug</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;vlan link add&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">vlan</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">oci_vcn_vlan_name</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$iface</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$vltag</span><span style="color: #CE9178">)</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">exit</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">$?</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">link</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">add</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">link</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$macvlan</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">name</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$vlan</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">type</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">vlan</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">id</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$vltag</span><span style="color: #D4D4D4"> </span><span style="color: #D7BA7D">\</span></span>
<span class="line"><span style="color: #D4D4D4">            || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot create VLAN </span><span style="color: #9CDCFE">$vlan</span><span style="color: #CE9178"> on MAC VLAN </span><span style="color: #9CDCFE">$macvlan</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># use namespace, if option</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">nscmd</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">dev=&quot;${</span><span style="color: #9CDCFE">vlan</span><span style="color: #D4D4D4">:-</span><span style="color: #9CDCFE">$iface</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">nscmd</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;netns exec </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$IP</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># move the iface(s) to the target namespace</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$macvlan</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #DCDCAA">oci_vcn_debug</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;macvlan link move </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">link</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">set</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">dev</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$macvlan</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">netns</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$ns</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot move MAC VLAN </span><span style="color: #9CDCFE">$macvlan</span><span style="color: #CE9178"> into namespace </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_debug</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$dev</span><span style="color: #CE9178"> link move </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">link</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">set</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">dev</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$dev</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">netns</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$ns</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot move interface </span><span style="color: #9CDCFE">$dev</span><span style="color: #CE9178"> into namespace </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># add IP address to iface:</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># the netmask is specified to create a route in the main route table</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># if this iface is on the same subnet as another iface then the route will not have an effect</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># (until the other iface is removed)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">oci_vcn_debug</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;addr </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178">/</span><span style="color: #9CDCFE">$sbits</span><span style="color: #CE9178"> add on </span><span style="color: #9CDCFE">$dev</span><span style="color: #CE9178"> ns &#39;</span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&#39;&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$nscmd</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">addr</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">add</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178">/</span><span style="color: #9CDCFE">$sbits</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">dev</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$dev</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot add IP address </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178">/</span><span style="color: #9CDCFE">$sbits</span><span style="color: #CE9178"> on interface </span><span style="color: #9CDCFE">$dev</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$macvlan</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># set vlans up</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_debug</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;vlans set up&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$nscmd</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">link</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">set</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">dev</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$macvlan</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">mtu</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$MTU</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">up</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot set MAC VLAN </span><span style="color: #9CDCFE">$macvlan</span><span style="color: #CE9178"> up&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$nscmd</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">link</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">set</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">dev</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$vlan</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">mtu</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$MTU</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">up</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot set VLAN </span><span style="color: #9CDCFE">$vlan</span><span style="color: #CE9178"> up&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">else</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_debug</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$iface</span><span style="color: #CE9178"> set up&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$nscmd</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">link</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">set</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">dev</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$iface</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">mtu</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$MTU</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">up</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot set interface </span><span style="color: #9CDCFE">$iface</span><span style="color: #CE9178"> MTU&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">oci_vcn_info</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;added IP address </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178"> on interface </span><span style="color: #9CDCFE">$dev</span><span style="color: #CE9178"> with MTU </span><span style="color: #9CDCFE">$MTU</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">echo</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$dev</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_ip_addr_del_iface</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ip_i=</span><span style="color: #9CDCFE">$1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">iface=&quot;${</span><span style="color: #9CDCFE">IP_IFACES</span><span style="color: #CE9178">[$ip_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ns=&quot;${</span><span style="color: #9CDCFE">IP_NSS</span><span style="color: #CE9178">[$ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">vlan=&quot;${</span><span style="color: #9CDCFE">IP_VLANS</span><span style="color: #CE9178">[$ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">secad=&quot;${</span><span style="color: #9CDCFE">IP_SECADS</span><span style="color: #CE9178">[$ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">nscmd</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">nscmd</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;netns exec </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$IP</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$secad</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> != </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$YES</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] &amp;&amp; [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$vlan</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># delete vlan and macvlan, removes the addrs (pri and sec) as well</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_debug</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178"> link delete&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">vltag=&quot;${</span><span style="color: #9CDCFE">IP_VLTAGS</span><span style="color: #CE9178">[$ip_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">macvlan</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">macvlan</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">oci_vcn_macvlan_name</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$iface</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$vltag</span><span style="color: #CE9178">)</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">exit</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">$?</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$nscmd</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">link</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">del</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">link</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$vlan</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">dev</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$macvlan</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot remove VLAN </span><span style="color: #9CDCFE">$vlan</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_info</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;removed VLAN </span><span style="color: #9CDCFE">$vlan</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">else</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># delete addr from phys iface</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># deleting namespace will move phys iface back to main</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># note that we may be deleting sec addr from a vlan here</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">addr=&quot;${</span><span style="color: #9CDCFE">IP_ADDRS</span><span style="color: #CE9178">[$ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">dev=&quot;${</span><span style="color: #9CDCFE">vlan</span><span style="color: #D4D4D4">:-</span><span style="color: #9CDCFE">$iface</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">bits</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_SBITSS</span><span style="color: #CE9178">[$ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">        [ </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$secad</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> != </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$YES</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #9CDCFE">bits</span><span style="color: #D4D4D4">=</span><span style="color: #B5CEA8">32</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_debug</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;addr </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178"> del ns &#39;</span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&#39; dev </span><span style="color: #9CDCFE">$dev</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$nscmd</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">addr</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">del</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178">/</span><span style="color: #9CDCFE">$bits</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">dev</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$dev</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot remove IP address </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178">/</span><span style="color: #9CDCFE">$bits</span><span style="color: #CE9178"> from interface </span><span style="color: #9CDCFE">$dev</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_info</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;removed IP address </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178"> from interface </span><span style="color: #9CDCFE">$dev</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_ip_addr_add</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">md_i=</span><span style="color: #9CDCFE">$1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">mac=&quot;${</span><span style="color: #9CDCFE">MD_MACS</span><span style="color: #CE9178">[$md_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">addr=&quot;${</span><span style="color: #9CDCFE">MD_ADDRS</span><span style="color: #CE9178">[$md_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">ns</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">iface</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">nic_i</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">vltag</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># note that when adding an addr to a physical iface ip_i will be the index of the</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># addr, but when creating a vlan for addr ip_i will not be the vlan iface but its phys one</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ip_i</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$IS_VM</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># bm vnics&#39; physical ifaces are identified by nic index</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">nic_i</span><span style="color: #D4D4D4">=${</span><span style="color: #9CDCFE">MD_NIC_IS</span><span style="color: #D4D4D4">[$md_i]}</span></span>
<span class="line"><span style="color: #D4D4D4">        [ </span><span style="color: #9CDCFE">$nic_i</span><span style="color: #D4D4D4"> -lt ${#</span><span style="color: #9CDCFE">NIC_IP_IS</span><span style="color: #D4D4D4">[@]} ] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot find interface for NIC </span><span style="color: #9CDCFE">$nic_i</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">ip_i</span><span style="color: #D4D4D4">=${</span><span style="color: #9CDCFE">NIC_IP_IS</span><span style="color: #D4D4D4">[$nic_i]}</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">iface</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_IFACES</span><span style="color: #CE9178">[$ip_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">vltag</span><span style="color: #D4D4D4">=${</span><span style="color: #9CDCFE">MD_VLTAGS</span><span style="color: #D4D4D4">[$md_i]}</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">else</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># vm vnics&#39; physical ifaces are identified by matching mac</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">found</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">ip_i</span><span style="color: #D4D4D4">=</span><span style="color: #B5CEA8">0</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ip_mac</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">ip_mac</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_MACS</span><span style="color: #CE9178">[@]}&quot;</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$ip_mac</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$mac</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #9CDCFE">found</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;t&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">break</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">ip_i</span><span style="color: #D4D4D4">+=</span><span style="color: #B5CEA8">1</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">done</span></span>
<span class="line"><span style="color: #D4D4D4">        [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$found</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot find interface matching VNIC MAC </span><span style="color: #9CDCFE">$mac</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">iface</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_IFACES</span><span style="color: #CE9178">[$ip_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">nic_i</span><span style="color: #D4D4D4">=${</span><span style="color: #9CDCFE">IP_NIC_IS</span><span style="color: #D4D4D4">[$ip_i]}</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">vltag</span><span style="color: #D4D4D4">=</span><span style="color: #B5CEA8">0</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># check that there is no current addr on iface</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$IS_VM</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || [ </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">MD_VLTAGS</span><span style="color: #CE9178">[$md_i]}&quot;</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&quot;0&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># putting addr directly on iface</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ip_addr=&quot;${</span><span style="color: #9CDCFE">IP_ADDRS</span><span style="color: #CE9178">[$ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        [ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$ip_addr</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;IP address </span><span style="color: #9CDCFE">$ip_addr</span><span style="color: #CE9178"> already added on interface </span><span style="color: #9CDCFE">$iface</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># make sure physical iface/nic is up</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_STATES</span><span style="color: #CE9178">[$ip_i]}&quot;</span><span style="color: #D4D4D4"> != </span><span style="color: #CE9178">&quot;UP&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">link</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">set</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">dev</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$iface</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">up</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot set interface </span><span style="color: #9CDCFE">$iface</span><span style="color: #CE9178"> up&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># create namespace if requested</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">ns</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$USE_NS</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">ns</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">oci_vcn_ip_ns_create</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$nic_i</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$vltag</span><span style="color: #CE9178">)</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">exit</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">$?</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># if working on a physical iface we need to set its namespace so that any</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># vlan created subsequently will know how to find it</span></span>
<span class="line"><span style="color: #D4D4D4">        [ </span><span style="color: #9CDCFE">$vltag</span><span style="color: #D4D4D4"> -ne </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ] || </span><span style="color: #9CDCFE">IP_NSS</span><span style="color: #D4D4D4">[</span><span style="color: #9CDCFE">$ip_i</span><span style="color: #D4D4D4">]=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># add addr to iface (possibly creating vlan)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">dev</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">dev</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">oci_vcn_ip_addr_add_iface</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$md_i</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$ip_i</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">)</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">exit</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">$?</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># setup routes</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">oci_vcn_ip_routing_add</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$md_i</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$nic_i</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$dev</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$ns</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># if namespace then wait for changes and start services</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">sleep</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># namespace changes seem to take time</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_ip_ns_svcs_start</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$ns</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_ip_sec_addr_add</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">iface_ip_i=</span><span style="color: #9CDCFE">$1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">addr=</span><span style="color: #9CDCFE">$2</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">iface=&quot;${</span><span style="color: #9CDCFE">IP_IFACES</span><span style="color: #CE9178">[$iface_ip_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">vlan=&quot;${</span><span style="color: #9CDCFE">IP_VLANS</span><span style="color: #CE9178">[$iface_ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">dev=&quot;${</span><span style="color: #9CDCFE">vlan</span><span style="color: #D4D4D4">:-</span><span style="color: #9CDCFE">$iface</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ns=&quot;${</span><span style="color: #9CDCFE">IP_NSS</span><span style="color: #CE9178">[$iface_ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">nscmd</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">nsinfo</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># config routing</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">oci_vcn_ip_routing_sec_addr_add</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$iface_ip_i</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$addr</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># config the addr on the iface</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">nscmd</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;netns exec </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$IP</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">nsinfo</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot; in namespace </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">oci_vcn_info</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;adding secondary IP address </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178"> to interface (or VLAN) </span><span style="color: #9CDCFE">$dev$nsinfo</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$nscmd</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">addr</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">add</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178">/32</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">dev</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$dev</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot add secondary IP address </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178"> on interface </span><span style="color: #9CDCFE">$dev$nsinfo</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_ip_sec_addr_del</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ip_i=</span><span style="color: #9CDCFE">$1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">deconfig_all=</span><span style="color: #9CDCFE">$2</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">addr=</span><span style="color: #D4D4D4">${</span><span style="color: #9CDCFE">IP_ADDRS</span><span style="color: #D4D4D4">[$ip_i]}</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">iface=</span><span style="color: #D4D4D4">${</span><span style="color: #9CDCFE">IP_IFACES</span><span style="color: #D4D4D4">[$ip_i]}</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">vlan=&quot;${</span><span style="color: #9CDCFE">IP_VLANS</span><span style="color: #CE9178">[$ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">dev=&quot;${</span><span style="color: #9CDCFE">vlan</span><span style="color: #D4D4D4">:-</span><span style="color: #9CDCFE">$iface</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ns=&quot;${</span><span style="color: #9CDCFE">IP_NSS</span><span style="color: #CE9178">[$ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">nscmd</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">nsinfo</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    [ </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_SECADS</span><span style="color: #CE9178">[$ip_i]}&quot;</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$YES</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;not a secondary IP address: </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># remove the addr on the iface (see comments in add)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># no need if deconfig all and on a vlan or in namespace</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$deconfig_all</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || ([ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$vlan</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] &amp;&amp; [ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]); </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$deconfig_all</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] &amp;&amp; [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">nscmd</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;netns exec </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$IP</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">nsinfo</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot; in namespace </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_info</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;removing secondary IP address </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178"> from interface (or VLAN) </span><span style="color: #9CDCFE">$dev$nsinfo</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$nscmd</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">addr</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">del</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178">/32</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">dev</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$dev</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot remove IP address </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178"> on interface </span><span style="color: #9CDCFE">$dev</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># remove the routing (see comments in add)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">oci_vcn_ip_routing_sec_addr_del</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$ip_i</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$addr</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_sec_addr_is_provisioned</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">find_addr=</span><span style="color: #9CDCFE">$1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">find_vnic=</span><span style="color: #9CDCFE">$2</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">i</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">found</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">i</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">seq</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">0</span><span style="color: #CE9178"> $((${</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">SEC_ADDRS</span><span style="color: #CE9178">[@]} </span><span style="color: #D4D4D4">-</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">1</span><span style="color: #CE9178">)))</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">addr</span><span style="color: #D4D4D4">=${</span><span style="color: #9CDCFE">SEC_ADDRS</span><span style="color: #D4D4D4">[$i]}</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">vnic</span><span style="color: #D4D4D4">=${</span><span style="color: #9CDCFE">SEC_VNICS</span><span style="color: #D4D4D4">[$i]}</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$find_addr</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] &amp;&amp; [ </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$find_vnic</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$vnic</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">found</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;t&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">break</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">done</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">echo</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$found</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_ip_addr_del</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-ir</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ip_i=</span><span style="color: #9CDCFE">$1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ns=&quot;${</span><span style="color: #9CDCFE">IP_NSS</span><span style="color: #CE9178">[$ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">secad=&quot;${</span><span style="color: #9CDCFE">IP_SECADS</span><span style="color: #CE9178">[$ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    [ </span><span style="color: #9CDCFE">$ip_i</span><span style="color: #D4D4D4"> -ne </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot remove primary VNIC&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$secad</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> != </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$YES</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #6A9955"># stop services in namespace</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #DCDCAA">oci_vcn_ip_ns_svcs_stop</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$ns</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># remove routing</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_ip_routing_del</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$ip_i</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># remove addr</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">oci_vcn_ip_addr_del_iface</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$ip_i</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$secad</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> != </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$YES</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] &amp;&amp; [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># delete namespace</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_ip_ns_del</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$ns</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">sleep</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># namespace changes seem to take time</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_ip_ifaces_read</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ns=&quot;</span><span style="color: #9CDCFE">$1</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">nscmd</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">iface_datas</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># change ip command to use namespace</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">nscmd</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;netns exec </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$IP</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># read the interfaces in namespace (if any)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># mapfile will create array with each line an element</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">mapfile</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-t</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">iface_datas</span><span style="color: #D4D4D4"> &lt; </span><span style="color: #CE9178">&lt;(</span><span style="color: #9CDCFE">$IP</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$nscmd</span><span style="color: #CE9178"> addr show </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">awk</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-f</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$IFACE_AWK_SCRIPT</span><span style="color: #CE9178">)</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot read IP addresses&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ ${#</span><span style="color: #9CDCFE">iface_datas</span><span style="color: #D4D4D4">[@]} -eq </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># if reading physical ifaces, must be at least 1</span></span>
<span class="line"><span style="color: #D4D4D4">        [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot locate interfaces&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># empty namespace: probably result of a VM VNIC delete</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># note empty namespaces do not survive reboot</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">netns</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">del</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$ns</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot delete empty namespace </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_warn</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;deleted empty namespace </span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">else</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">nsna=&quot;${</span><span style="color: #9CDCFE">ns</span><span style="color: #D4D4D4">:-</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ip_i=</span><span style="color: #D4D4D4">${#</span><span style="color: #9CDCFE">IP_MACS</span><span style="color: #D4D4D4">[@]} </span><span style="color: #6A9955"># continue from previous ns (if any)</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">line</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">line</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">iface_datas</span><span style="color: #CE9178">[@]}&quot;</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #6A9955"># line items are in order printed by awk script print</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #6A9955"># note that $NA is used to mean null (i.e. not set)</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #DCDCAA">oci_vcn_debug</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;iface line: </span><span style="color: #9CDCFE">$line</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-a</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">iface_data=</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">$line</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">iface</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">iface_data</span><span style="color: #CE9178">[1]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #6A9955"># filter out virtual interfaces if VM (assume created by user for other purpose)</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$IS_VM</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || [ -z </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">VIRTUAL_IFACES</span><span style="color: #CE9178">[$iface]}&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">mac</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">iface_data</span><span style="color: #CE9178">[0]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #9CDCFE">IP_MACS</span><span style="color: #D4D4D4">+=(</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$mac</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #9CDCFE">IP_NSS</span><span style="color: #D4D4D4">+=(</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$nsna</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #9CDCFE">IP_IFACES</span><span style="color: #D4D4D4">+=(</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$iface</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #9CDCFE">IP_ADDRS</span><span style="color: #D4D4D4">+=(</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">iface_data</span><span style="color: #CE9178">[2]}&quot;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #9CDCFE">IP_SBITSS</span><span style="color: #D4D4D4">+=(</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">iface_data</span><span style="color: #CE9178">[3]}&quot;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #9CDCFE">IP_STATES</span><span style="color: #D4D4D4">+=(</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">iface_data</span><span style="color: #CE9178">[4]}&quot;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #9CDCFE">IP_VLANS</span><span style="color: #D4D4D4">+=(</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">iface_data</span><span style="color: #CE9178">[5]}&quot;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #9CDCFE">IP_VLTAGS</span><span style="color: #D4D4D4">+=(</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">iface_data</span><span style="color: #CE9178">[6]}&quot;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">secad</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">iface_data</span><span style="color: #CE9178">[7]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #9CDCFE">IP_SECADS</span><span style="color: #D4D4D4">+=(</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$secad</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">                [ </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$secad</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$YES</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #DCDCAA">IP_I_BY_MAC[</span><span style="color: #DCDCAA">&quot;</span><span style="color: #9CDCFE">$mac</span><span style="color: #DCDCAA">&quot;</span><span style="color: #DCDCAA">]</span><span style="color: #D4D4D4">=</span><span style="color: #9CDCFE">$ip_i</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># primary addrs only</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #9CDCFE">ip_i</span><span style="color: #D4D4D4">+=</span><span style="color: #B5CEA8">1</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">done</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_ip_read</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">IP_I_BY_MAC</span><span style="color: #D4D4D4">=()</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">IP_MACS</span><span style="color: #D4D4D4">=()</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">IP_NSS</span><span style="color: #D4D4D4">=()</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">IP_IFACES</span><span style="color: #D4D4D4">=()</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">IP_ADDRS</span><span style="color: #D4D4D4">=()</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">IP_SADDRS</span><span style="color: #D4D4D4">=()</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">IP_SBITSS</span><span style="color: #D4D4D4">=()</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">IP_VIRTRTS</span><span style="color: #D4D4D4">=()</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">IP_STATES</span><span style="color: #D4D4D4">=()</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">IP_VLANS</span><span style="color: #D4D4D4">=()</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">IP_VLTAGS</span><span style="color: #D4D4D4">=()</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">IP_SECADS</span><span style="color: #D4D4D4">=()</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">IP_SRCS</span><span style="color: #D4D4D4">=()</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">IP_NIC_IS</span><span style="color: #D4D4D4">=()</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">NIC_IP_IS</span><span style="color: #D4D4D4">=()</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">NIC_I_BY_PHYS_IP_I</span><span style="color: #D4D4D4">=()</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># read the non-namespace ifaces and any addrs on them</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">oci_vcn_ip_ifaces_read</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># read ifaces in all the namespaces (if any), note some os&#39;s don&#39;t support netns</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">mapfile</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-t</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">nss</span><span style="color: #D4D4D4"> &lt; </span><span style="color: #CE9178">&lt;(</span><span style="color: #9CDCFE">$IP</span><span style="color: #CE9178"> netns </span><span style="color: #D4D4D4">2&gt;</span><span style="color: #CE9178">/dev/null)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ns</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">ns</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">nss</span><span style="color: #CE9178">[@]}&quot;</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_ip_ifaces_read</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$ns</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">done</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># set vltag 0 (for phys ifaces) and read os routes for all ifaces</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ip_i</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">ip_i</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">seq</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">0</span><span style="color: #CE9178"> $((${</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">IP_MACS</span><span style="color: #CE9178">[@]} </span><span style="color: #D4D4D4">-</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">1</span><span style="color: #CE9178">)))</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># any iface w/o vltag has tag 0</span></span>
<span class="line"><span style="color: #D4D4D4">        [ -n </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_VLTAGS</span><span style="color: #CE9178">[$ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #9CDCFE">IP_VLTAGS</span><span style="color: #D4D4D4">[</span><span style="color: #9CDCFE">$ip_i</span><span style="color: #D4D4D4">]=</span><span style="color: #B5CEA8">0</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_ip_routes_read</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$ip_i</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">done</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># find the &quot;physical&quot; iface indices: vltag 0 and not secondary addr</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># note vm ifaces are considered physical</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># these may not be in nic index order due to inclusion in namespaces (see next)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">tmpfile=$(</span><span style="color: #DCDCAA">mktemp</span><span style="color: #CE9178"> /tmp/oci_vcn_ifaces.XXXXX)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-A</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ip_i_by_phys_iface</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">ip_i</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">seq</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">0</span><span style="color: #CE9178"> $((${</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">IP_MACS</span><span style="color: #CE9178">[@]} </span><span style="color: #D4D4D4">-</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">1</span><span style="color: #CE9178">)))</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ ${</span><span style="color: #9CDCFE">IP_VLTAGS</span><span style="color: #D4D4D4">[$ip_i]} -eq </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ] &amp;&amp; [ </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_SECADS</span><span style="color: #CE9178">[$ip_i]}&quot;</span><span style="color: #D4D4D4"> != </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$YES</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #6A9955"># physical iface/nic</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">iface</span><span style="color: #D4D4D4">=${</span><span style="color: #9CDCFE">IP_IFACES</span><span style="color: #D4D4D4">[$ip_i]}</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">ip_i_by_phys_iface</span><span style="color: #D4D4D4">[</span><span style="color: #9CDCFE">$iface</span><span style="color: #D4D4D4">]=</span><span style="color: #9CDCFE">$ip_i</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #DCDCAA">echo</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$iface</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> &gt;&gt; </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$tmpfile</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">NIC_I_BY_PHYS_IP_I</span><span style="color: #D4D4D4">[</span><span style="color: #9CDCFE">$ip_i</span><span style="color: #D4D4D4">]=</span><span style="color: #B5CEA8">-1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">done</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># sort physical ifaces by first number (either at end or in middle) in iface name</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># this will provide the nic index</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">nic_i=</span><span style="color: #B5CEA8">0</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">iface</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">iface</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">cat</span><span style="color: #CE9178"> &quot;</span><span style="color: #9CDCFE">$tmpfile</span><span style="color: #CE9178">&quot; </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">awk</span><span style="color: #CE9178"> </span><span style="color: #569CD6">--</span><span style="color: #CE9178"> &#39;{ match($1, /[0-9]+/); print substr($1, RSTART, RLENGTH), $1 }&#39; </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">sort</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-n</span><span style="color: #CE9178"> </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">cut</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-f</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">2</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-d</span><span style="color: #CE9178"> &#39; &#39;)</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">ip_i</span><span style="color: #D4D4D4">=${</span><span style="color: #9CDCFE">ip_i_by_phys_iface</span><span style="color: #D4D4D4">[$iface]}</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">NIC_IP_IS</span><span style="color: #D4D4D4">+=(</span><span style="color: #9CDCFE">$ip_i</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">NIC_I_BY_PHYS_IP_I</span><span style="color: #D4D4D4">[</span><span style="color: #9CDCFE">$ip_i</span><span style="color: #D4D4D4">]=</span><span style="color: #9CDCFE">$nic_i</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">nic_i</span><span style="color: #D4D4D4">+=</span><span style="color: #B5CEA8">1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">done</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">rm</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$tmpfile</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># for each iface (phys or vlan) get nic index</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">ip_i</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">seq</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">0</span><span style="color: #CE9178"> $((${</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">IP_MACS</span><span style="color: #CE9178">[@]} </span><span style="color: #D4D4D4">-</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">1</span><span style="color: #CE9178">)))</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">iface</span><span style="color: #D4D4D4">=${</span><span style="color: #9CDCFE">IP_IFACES</span><span style="color: #D4D4D4">[$ip_i]}</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">phys_ip_i=</span><span style="color: #D4D4D4">${</span><span style="color: #9CDCFE">ip_i_by_phys_iface</span><span style="color: #D4D4D4">[$iface]}</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">IP_NIC_IS</span><span style="color: #D4D4D4">[</span><span style="color: #9CDCFE">$ip_i</span><span style="color: #D4D4D4">]=${</span><span style="color: #9CDCFE">NIC_I_BY_PHYS_IP_I</span><span style="color: #D4D4D4">[$phys_ip_i]}</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">done</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># fix up missing nic index for bms (see also oci_vcn_md_read): bms will be missing nic index metadata</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># if they were created before and have not had a vnic attached or detached since 8/23/17.</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># if there is a secondary vnic created and configured (before 8/23/17) we can tell it is a bm</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># because there will either be configured vlans or more vnics than physical ifaces.</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># note that gen 2 shapes are post 8/23/17 and, hence, will have nic indices already set.</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># a missing nic index for an old bm will not matter if there are no vnics to configure.</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ ${#</span><span style="color: #9CDCFE">MD_NIC_IS</span><span style="color: #D4D4D4">[@]} -eq </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ] &amp;&amp; [ ${#</span><span style="color: #9CDCFE">NIC_IP_IS</span><span style="color: #D4D4D4">[@]} -eq </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> ] &amp;&amp; </span><span style="color: #D7BA7D">\</span></span>
<span class="line"><span style="color: #D4D4D4">        ([ ${#</span><span style="color: #9CDCFE">IP_MACS</span><span style="color: #D4D4D4">[@]} -gt </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> ] || [ ${#</span><span style="color: #9CDCFE">MD_MACS</span><span style="color: #D4D4D4">[@]} -gt </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> ]); </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># configured or new secondaries</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">md_i</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">md_i</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">seq</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">0</span><span style="color: #CE9178"> $((${</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">MD_MACS</span><span style="color: #CE9178">[@]} </span><span style="color: #D4D4D4">-</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">1</span><span style="color: #CE9178">)))</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">MD_NIC_IS</span><span style="color: #D4D4D4">+=(</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">done</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_info</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;legacy BM instance detected&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">IS_VM</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_read</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># assumes md info is already read</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># reads ip configs and creates single array of all macs</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># (fixes vm interfaces if random mac)</span></span>
<span class="line"><span style="color: #D4D4D4">    [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$IP</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot find ip command&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">warn_ifaces</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">attempt</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">attempt</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> 1 2; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># initialize md/ip shared arrays</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">MACS</span><span style="color: #D4D4D4">=(</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">MD_MACS</span><span style="color: #CE9178">[@]}&quot;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># read all of ip config info and see if it matches md info</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_ip_read</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">MD_CONFIGS</span><span style="color: #D4D4D4">=()</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">md_i=</span><span style="color: #B5CEA8">0</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">mac</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">mac</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">MD_MACS</span><span style="color: #CE9178">[@]}&quot;</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">MD_CONFIGS</span><span style="color: #D4D4D4">[</span><span style="color: #9CDCFE">$md_i</span><span style="color: #D4D4D4">]=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ip_i=</span><span style="color: #D4D4D4">${</span><span style="color: #9CDCFE">IP_I_BY_MAC</span><span style="color: #D4D4D4">[$mac]:-</span><span style="color: #9CDCFE">-1</span><span style="color: #D4D4D4">}</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #9CDCFE">$ip_i</span><span style="color: #D4D4D4"> -lt </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #6A9955"># if there is no corresponding iface mac: add</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #6A9955"># note ifaces with random macs will be detected below and this will be retried</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #9CDCFE">MD_CONFIGS</span><span style="color: #D4D4D4">[</span><span style="color: #9CDCFE">$md_i</span><span style="color: #D4D4D4">]=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$ADD</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">else</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">addr</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_ADDRS</span><span style="color: #CE9178">[$ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #6A9955"># matching mac iface does not have address: add</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #6A9955"># make sure it is not a (corrupted) vlan that had been configured previously</span></span>
<span class="line"><span style="color: #D4D4D4">                    [ ${</span><span style="color: #9CDCFE">IP_VLTAGS</span><span style="color: #D4D4D4">[$ip_i]} -eq </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;VLAN (with MAC </span><span style="color: #9CDCFE">$mac</span><span style="color: #CE9178">) configured but missing IP address (must manually fix)&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #9CDCFE">MD_CONFIGS</span><span style="color: #D4D4D4">[</span><span style="color: #9CDCFE">$md_i</span><span style="color: #D4D4D4">]=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$ADD</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">md_i</span><span style="color: #D4D4D4">+=</span><span style="color: #B5CEA8">1</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">done</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ip_i=</span><span style="color: #B5CEA8">0</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">IP_CONFIGS</span><span style="color: #D4D4D4">=()</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">retry</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">warn_ifaces</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-A</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">new_macs=</span><span style="color: #D4D4D4">() # for deduping secondary addr macs</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">mac</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_MACS</span><span style="color: #CE9178">[@]}&quot;</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">IP_CONFIGS</span><span style="color: #D4D4D4">[</span><span style="color: #9CDCFE">$ip_i</span><span style="color: #D4D4D4">]=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">addr</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_ADDRS</span><span style="color: #CE9178">[$ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #6A9955"># note that the primary vnic will be matched up (permanently)</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">md_i=</span><span style="color: #D4D4D4">${</span><span style="color: #9CDCFE">MD_I_BY_MAC</span><span style="color: #D4D4D4">[$mac]:-</span><span style="color: #9CDCFE">-1</span><span style="color: #D4D4D4">}</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #9CDCFE">$md_i</span><span style="color: #D4D4D4"> -lt </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #6A9955"># no metadata mac corresponding to ip mac</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">iface</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_IFACES</span><span style="color: #CE9178">[$ip_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #6A9955"># addr is configured: should be deleted</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #6A9955"># bm case (in vm case ifaces are auto-deleted when vnic is detached)</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #9CDCFE">IP_CONFIGS</span><span style="color: #D4D4D4">[</span><span style="color: #9CDCFE">$ip_i</span><span style="color: #D4D4D4">]=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$DELETE</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">elif</span><span style="color: #D4D4D4"> [ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$IS_VM</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #6A9955"># bm iface mac w/o addr and w/o md mac:</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #6A9955"># skip if phys iface, else addr deleted w/o deleting vlan?</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ ${</span><span style="color: #9CDCFE">IP_VLTAGS</span><span style="color: #D4D4D4">[$ip_i]} -ne </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">                        </span><span style="color: #9CDCFE">IP_CONFIGS</span><span style="color: #D4D4D4">[</span><span style="color: #9CDCFE">$ip_i</span><span style="color: #D4D4D4">]=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$DELETE</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                        </span><span style="color: #9CDCFE">warn_ifaces</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$warn_ifaces</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$iface</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">else</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #6A9955"># vm iface mac w/o addr and w/o md mac: assume random mac</span></span>
<span class="line"><span style="color: #D4D4D4">                    ([ </span><span style="color: #9CDCFE">$attempt</span><span style="color: #D4D4D4"> -eq </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> ] &amp;&amp; [ </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_STATES</span><span style="color: #CE9178">[$ip_i]}&quot;</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&#39;DOWN&#39;</span><span style="color: #D4D4D4"> ]) || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;interface </span><span style="color: #9CDCFE">$iface</span><span style="color: #CE9178"> with MAC </span><span style="color: #9CDCFE">$mac</span><span style="color: #CE9178"> does not have corresponding metadata&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #6A9955"># assume vm case 1st since less likely addr was deleted</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #6A9955"># attempt mac fix by turning iface up, then retry</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #6A9955"># this is probably an Intel driver problem</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #6A9955"># could look at /sys/class/net/&lt;iface&gt;/addr_assign_type</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #9CDCFE">$IP</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">link</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">set</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">dev</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$iface</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">up</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot set interface </span><span style="color: #9CDCFE">$iface</span><span style="color: #CE9178"> up&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #9CDCFE">retry</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;t&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -z </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">new_macs</span><span style="color: #CE9178">[$mac]}&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #9CDCFE">new_macs</span><span style="color: #D4D4D4">[</span><span style="color: #9CDCFE">$mac</span><span style="color: #D4D4D4">]=</span><span style="color: #CE9178">&#39;t&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #9CDCFE">MACS</span><span style="color: #D4D4D4">+=(</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$mac</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">) </span><span style="color: #6A9955"># accumulate all unique macs</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #6A9955"># TODO else validate for consistency?: addr, vltag, subnet, virtrt</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">elif</span><span style="color: #D4D4D4"> [ </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_SECADS</span><span style="color: #CE9178">[$ip_i]}&quot;</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$YES</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">is_prov</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">oci_vcn_sec_addr_is_provisioned</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178"> &quot;${</span><span style="color: #9CDCFE">MD_VNICS</span><span style="color: #CE9178">[$md_i]}&quot;)</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$is_prov</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #9CDCFE">IP_CONFIGS</span><span style="color: #D4D4D4">[</span><span style="color: #9CDCFE">$ip_i</span><span style="color: #D4D4D4">]=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$DELETE</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">ip_i</span><span style="color: #D4D4D4">+=</span><span style="color: #B5CEA8">1</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">done</span></span>
<span class="line"><span style="color: #D4D4D4">        [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$retry</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #C586C0">break</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">done</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$warn_ifaces</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_warn</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;no VNIC (or MAC does not match) and no address, interfaces will be marked for delete:</span><span style="color: #9CDCFE">$warn_ifaces</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_config_or_deconfig_sec_addrs</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">do_config=&quot;</span><span style="color: #9CDCFE">$1</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># config if not empty, else deconfig</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">found</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># vnics must be configured, whether config or deconfig secondary addrs</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">i</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">i</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">seq</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">0</span><span style="color: #CE9178"> $((${</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">SEC_ADDRS</span><span style="color: #CE9178">[@]} </span><span style="color: #D4D4D4">-</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">1</span><span style="color: #CE9178">)))</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">addr</span><span style="color: #D4D4D4">=${</span><span style="color: #9CDCFE">SEC_ADDRS</span><span style="color: #D4D4D4">[$i]}</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">vnic</span><span style="color: #D4D4D4">=${</span><span style="color: #9CDCFE">SEC_VNICS</span><span style="color: #D4D4D4">[$i]}</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># find vnic&#39;s mac</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">mac</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">md_i</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">md_i</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">seq</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">0</span><span style="color: #CE9178"> $((${</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">MD_MACS</span><span style="color: #CE9178">[@]} </span><span style="color: #D4D4D4">-</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">1</span><span style="color: #CE9178">)))</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$vnic</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">MD_VNICS</span><span style="color: #CE9178">[$md_i]}&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #9CDCFE">mac</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">MD_MACS</span><span style="color: #CE9178">[$md_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">break</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">done</span></span>
<span class="line"><span style="color: #D4D4D4">        [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$mac</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot find VNIC for secondary IP address </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178"> on </span><span style="color: #9CDCFE">$vnic</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># find mac in ip config</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">iface_ip_i=</span><span style="color: #B5CEA8">-1</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">already_config</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ip_i</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">ip_i</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">seq</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">0</span><span style="color: #CE9178"> $((${</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">IP_MACS</span><span style="color: #CE9178">[@]} </span><span style="color: #D4D4D4">-</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">1</span><span style="color: #CE9178">)))</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$mac</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_MACS</span><span style="color: #CE9178">[$ip_i]}&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># put on this iface if not already configured</span></span>
<span class="line"><span style="color: #D4D4D4">                [ </span><span style="color: #9CDCFE">$iface_ip_i</span><span style="color: #D4D4D4"> -ge </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ] || </span><span style="color: #9CDCFE">iface_ip_i</span><span style="color: #D4D4D4">=</span><span style="color: #9CDCFE">$ip_i</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># 1st is interface (secondary addrs come after)</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_ADDRS</span><span style="color: #CE9178">[$ip_i]}&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># already configured</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #9CDCFE">already_config</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;t&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #C586C0">break</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">done</span></span>
<span class="line"><span style="color: #D4D4D4">        [ </span><span style="color: #9CDCFE">$iface_ip_i</span><span style="color: #D4D4D4"> -ge </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot find interface for secondary IP address </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178"> on </span><span style="color: #9CDCFE">$vnic</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$do_config</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] &amp;&amp; [ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$already_config</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># configure</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #DCDCAA">oci_vcn_ip_sec_addr_add</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$iface_ip_i</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$addr</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">found</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;t&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">elif</span><span style="color: #D4D4D4"> [ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$do_config</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] &amp;&amp; [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$already_config</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># deconfigure</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #6A9955"># note this path is only if deconfiguring just the secondaries</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #DCDCAA">oci_vcn_ip_sec_addr_del</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$ip_i</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">found</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;t&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">done</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">echo</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$found</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_config</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">found</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">mac</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-A</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">configed</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># fix up config: md will indicate adds, ip deletes</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">md_i</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">md_i</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">seq</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">0</span><span style="color: #CE9178"> $((${</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">MD_CONFIGS</span><span style="color: #CE9178">[@]} </span><span style="color: #D4D4D4">-</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">1</span><span style="color: #CE9178">)))</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">config</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">MD_CONFIGS</span><span style="color: #CE9178">[$md_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$config</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$ADD</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #DCDCAA">oci_vcn_info</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;adding IP config for VNIC MAC ${</span><span style="color: #9CDCFE">MD_MACS</span><span style="color: #CE9178">[$md_i]} with id ${</span><span style="color: #9CDCFE">MD_VNICS</span><span style="color: #CE9178">[$md_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #DCDCAA">oci_vcn_ip_addr_add</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$md_i</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">found</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;t&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">done</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">del_vmac</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ip_i</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">ip_i</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">seq</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">0</span><span style="color: #CE9178"> $((${</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">IP_CONFIGS</span><span style="color: #CE9178">[@]} </span><span style="color: #D4D4D4">-</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">1</span><span style="color: #CE9178">)))</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">config</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_CONFIGS</span><span style="color: #CE9178">[$ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$config</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$DELETE</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #6A9955"># del all pri addrs and sec addrs (unless its vlan is being deleted)</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">mac</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_MACS</span><span style="color: #CE9178">[$ip_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">secad</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_SECADS</span><span style="color: #CE9178">[$ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$secad</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> != </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$YES</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || [ </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$del_vmac</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> != </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$mac</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">addr</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_ADDRS</span><span style="color: #CE9178">[$ip_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #DCDCAA">oci_vcn_info</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;removing IP config of address </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178"> from MAC </span><span style="color: #9CDCFE">$mac</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #DCDCAA">oci_vcn_ip_addr_del</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$ip_i</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #9CDCFE">found</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;t&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #6A9955"># keep track of last deleted vlan</span></span>
<span class="line"><span style="color: #D4D4D4">                [ </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_VLTAGS</span><span style="color: #CE9178">[$ip_i]}&quot;</span><span style="color: #D4D4D4"> -eq </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ] || </span><span style="color: #9CDCFE">del_vmac</span><span style="color: #D4D4D4">=</span><span style="color: #9CDCFE">$mac</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">done</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># config secondary addrs, if any</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">sec_addrs_found</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ ${#</span><span style="color: #9CDCFE">SEC_ADDRS</span><span style="color: #D4D4D4">[@]} -gt </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># reread config if there were changes so that secondaries are put in the correct place</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$found</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #DCDCAA">sleep</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># wait for newly created ifaces to settle</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #DCDCAA">oci_vcn_read</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">sec_addrs_found</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">oci_vcn_config_or_deconfig_sec_addrs</span><span style="color: #CE9178"> &#39;t&#39;)</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">exit</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">$?</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$found</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$sec_addrs_found</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #DCDCAA">oci_vcn_info</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;no changes, IP configuration is up-to-date&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_deconfig_all</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ip_i=</span><span style="color: #B5CEA8">0</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">found</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">mac</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">mac</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_MACS</span><span style="color: #CE9178">[@]}&quot;</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">addr</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_ADDRS</span><span style="color: #CE9178">[$ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># ip is configured</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #6A9955"># note that primaries are encountered first</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_SECADS</span><span style="color: #CE9178">[$ip_i]}&quot;</span><span style="color: #D4D4D4"> != </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$YES</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># primary addr</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #9CDCFE">$ip_i</span><span style="color: #D4D4D4"> -gt </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># skip pri vnic, pri addr</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">md_i=</span><span style="color: #D4D4D4">${</span><span style="color: #9CDCFE">MD_I_BY_MAC</span><span style="color: #D4D4D4">[$mac]:-</span><span style="color: #9CDCFE">-1</span><span style="color: #D4D4D4">}</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">missing</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot; missing&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">vnicmsg</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #9CDCFE">$md_i</span><span style="color: #D4D4D4"> -ge </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">vnicmsg</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot; with id ${</span><span style="color: #9CDCFE">MD_VNICS</span><span style="color: #CE9178">[$md_i]}&quot;</span><span style="color: #D4D4D4">; </span><span style="color: #9CDCFE">missing</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;&quot;</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #DCDCAA">oci_vcn_info</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;removing IP config of address </span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178"> for</span><span style="color: #9CDCFE">$missing</span><span style="color: #CE9178"> VNIC MAC </span><span style="color: #9CDCFE">$mac$vnicmsg</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #DCDCAA">oci_vcn_ip_addr_del</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$ip_i</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #9CDCFE">found</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;t&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">else</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># secondary addr</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #DCDCAA">oci_vcn_ip_sec_addr_del</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$ip_i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;t&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #9CDCFE">found</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;t&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">ip_i</span><span style="color: #D4D4D4">+=</span><span style="color: #B5CEA8">1</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">done</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$found</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_info</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;no changes, no IP configuration to delete&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_show</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">fmt=&quot;%-6s %-15s %-15s %-5s %-15s %-10s %-3s %-10s %-5s %-11s %-5s %-17s %s\n&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">printf</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$fmt</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">CONFIG</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ADDR</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">SPREFIX</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">SBITS</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">VIRTRT</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">NS</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">IND</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">IFACE</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">VLTAG</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">VLAN</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">STATE</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">MAC</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">VNIC</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">mac</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">mac</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">MACS</span><span style="color: #CE9178">[@]}&quot;</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># all known macs</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">config</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">addr</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">nic_i</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">vltag</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">sprefix</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">sbits</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">virtrt</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">ns</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">iface</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">vlan</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">state</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">vnic</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">md_i=</span><span style="color: #D4D4D4">${</span><span style="color: #9CDCFE">MD_I_BY_MAC</span><span style="color: #D4D4D4">[$mac]:-</span><span style="color: #9CDCFE">-1</span><span style="color: #D4D4D4">}</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #9CDCFE">$md_i</span><span style="color: #D4D4D4"> -ge </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># in md: ADD, or no change depending on ip info</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">config</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">MD_CONFIGS</span><span style="color: #CE9178">[$md_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">nic_i</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">MD_NIC_IS</span><span style="color: #CE9178">[$md_i]</span><span style="color: #D4D4D4">:-</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">addr</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">MD_ADDRS</span><span style="color: #CE9178">[$md_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">            [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$IS_VM</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #9CDCFE">vltag</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">MD_VLTAGS</span><span style="color: #CE9178">[$md_i]}&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># not used in vms</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">sprefix</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">MD_SPREFIXS</span><span style="color: #CE9178">[$md_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">sbits</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">MD_SBITSS</span><span style="color: #CE9178">[$md_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">virtrt</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">MD_VIRTRTS</span><span style="color: #CE9178">[$md_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">vnic</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">MD_VNICS</span><span style="color: #CE9178">[$md_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># find the ip info on this mac, note that there could be none, one,</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># or multiple addrs if secondaries addrs exist (they will come after primary)</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ip_i=</span><span style="color: #D4D4D4">${</span><span style="color: #9CDCFE">IP_I_BY_MAC</span><span style="color: #D4D4D4">[$mac]:-</span><span style="color: #9CDCFE">-1</span><span style="color: #D4D4D4">} </span><span style="color: #6A9955"># index of primary addr, if any</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #9CDCFE">$ip_i</span><span style="color: #D4D4D4"> -ge </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">pri_ip_i=</span><span style="color: #9CDCFE">$ip_i</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">secad</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">while</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">true</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #9CDCFE">secad</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_SECADS</span><span style="color: #CE9178">[$ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                [ </span><span style="color: #9CDCFE">$pri_ip_i</span><span style="color: #D4D4D4"> -eq </span><span style="color: #9CDCFE">$ip_i</span><span style="color: #D4D4D4"> ] || [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$secad</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #C586C0">break</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #9CDCFE">vlan</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_VLANS</span><span style="color: #CE9178">[$ip_i]</span><span style="color: #D4D4D4">:-</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #9CDCFE">iface</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_IFACES</span><span style="color: #CE9178">[$ip_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #9CDCFE">ns</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_NSS</span><span style="color: #CE9178">[$ip_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #9CDCFE">state</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_STATES</span><span style="color: #CE9178">[$ip_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">cfg</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_CONFIGS</span><span style="color: #CE9178">[$ip_i]</span><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                [ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$cfg</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #9CDCFE">config</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$cfg</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #9CDCFE">$md_i</span><span style="color: #D4D4D4"> -lt </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># not in md, fill with ip info</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #9CDCFE">addr</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_ADDRS</span><span style="color: #CE9178">[$ip_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #9CDCFE">sbits</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_SBITSS</span><span style="color: #CE9178">[$ip_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #9CDCFE">virtrt</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_VIRTRTS</span><span style="color: #CE9178">[$ip_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                    [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$IS_VM</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #9CDCFE">vltag</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_VLTAGS</span><span style="color: #CE9178">[$ip_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">elif</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$secad</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #9CDCFE">addr</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">IP_ADDRS</span><span style="color: #CE9178">[$ip_i]}&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #569CD6">local</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-i</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">nic_phys=</span><span style="color: #D4D4D4">${</span><span style="color: #9CDCFE">NIC_I_BY_PHYS_IP_I</span><span style="color: #D4D4D4">[$ip_i]}</span></span>
<span class="line"><span style="color: #D4D4D4">                [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$secad</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || [ </span><span style="color: #9CDCFE">$nic_phys</span><span style="color: #D4D4D4"> -lt </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ] || </span><span style="color: #9CDCFE">nic_i</span><span style="color: #D4D4D4">=</span><span style="color: #9CDCFE">$nic_phys</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># don&#39;t show if sec addr</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$secad</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #DCDCAA">printf</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$fmt</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$config</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$sprefix</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$sbits</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$virtrt</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$nic_i</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$iface</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$vltag</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$vlan</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$state</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$mac</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$vnic</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">else</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #DCDCAA">printf</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$fmt</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$config</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$NA</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #9CDCFE">ip_i</span><span style="color: #D4D4D4">+=</span><span style="color: #B5CEA8">1</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">done</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">else</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #DCDCAA">printf</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$fmt</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$config</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$addr</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$sprefix</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$sbits</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$virtrt</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$ns</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$nic_i</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$iface</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$vltag</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$vlan</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$state</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$mac</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$vnic</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">done</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_help</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">cat</span><span style="color: #D4D4D4"> &lt;&lt;</span><span style="color: #D4D4D4">EOF</span></span>
<span class="line"><span style="color: #CE9178">NAME</span></span>
<span class="line"><span style="color: #CE9178">    </span><span style="color: #9CDCFE">$THIS</span><span style="color: #CE9178"> -- display and configure Oracle OCI Virtual Cloud Networks on instance</span></span>
<span class="line"></span>
<span class="line"><span style="color: #CE9178">SYNOPSIS</span></span>
<span class="line"><span style="color: #CE9178">    </span><span style="color: #9CDCFE">$THIS</span><span style="color: #CE9178"> [-s] [-e &lt;IP address&gt; &lt;VNIC OCID&gt;]</span></span>
<span class="line"><span style="color: #CE9178">    </span><span style="color: #9CDCFE">$THIS</span><span style="color: #CE9178"> -c [-q] [-s] [-n [&lt;format&gt;] [-r]] [-e &lt;IP address&gt; &lt;VNIC OCID&gt; [-e ...]]</span></span>
<span class="line"><span style="color: #CE9178">    </span><span style="color: #9CDCFE">$THIS</span><span style="color: #CE9178"> -d [-q] [-s] [-e &lt;IP address&gt; &lt;VNIC OCID&gt;]</span></span>
<span class="line"></span>
<span class="line"><span style="color: #CE9178">DESCRIPTION</span></span>
<span class="line"><span style="color: #CE9178">    This shows the current OCI Virtual interface Cards provisioned in the cloud</span></span>
<span class="line"><span style="color: #CE9178">    and configured on this instance. When a secondary VNIC is provisioned in OCI it must</span></span>
<span class="line"><span style="color: #CE9178">    be explicitly configured on the instance using this script or similar commands.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #CE9178">    The first version of this command displays the currently provisioned VNICs and the</span></span>
<span class="line"><span style="color: #CE9178">    current IP configuration for this instance. VNICs that are not yet configured are</span></span>
<span class="line"><span style="color: #CE9178">    marked with &#39;</span><span style="color: #9CDCFE">$ADD</span><span style="color: #CE9178">&#39; and IP configurations that no longer have an associated VNIC</span></span>
<span class="line"><span style="color: #CE9178">    are marked with &#39;</span><span style="color: #9CDCFE">$DELETE</span><span style="color: #CE9178">&#39;.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #CE9178">    The second version, with -c, configures VNICs that do not have an IP configuration</span></span>
<span class="line"><span style="color: #CE9178">    and deletes the IP configurations of VNICs that are not currently provisioned.</span></span>
<span class="line"><span style="color: #CE9178">    This puts the instance IP configuration in sync with current OCI provisioning.</span></span>
<span class="line"><span style="color: #CE9178">    If one or more optional -e options are present the secondary IP addresses are</span></span>
<span class="line"><span style="color: #CE9178">    configured on the same interfaces as the corresponding VNIC.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #CE9178">    The configuring interfaces can optionally be placed inside separate network</span></span>
<span class="line"><span style="color: #CE9178">    namespaces. This is necessary when VNICs are in subnets (different VCNs) with</span></span>
<span class="line"><span style="color: #CE9178">    overlapping address blocks and the network applications are not bound directly</span></span>
<span class="line"><span style="color: #CE9178">    to interfaces. Network namespaces require applications to be launched in them</span></span>
<span class="line"><span style="color: #CE9178">    explicitly (via &#39;ip netns exec &lt;ns&gt;&#39;) in order to establish association with</span></span>
<span class="line"><span style="color: #CE9178">    the interface. When namespaces are not used, policy-based routing is configured</span></span>
<span class="line"><span style="color: #CE9178">    to provide a default route to the secondary VNIC\&#39;s virtual router (default</span></span>
<span class="line"><span style="color: #CE9178">    gateway) when the VNIC\&#39;s address is the source address.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #CE9178">    Bare Metal secondary VNICs are configured using VLANs (where there is no</span></span>
<span class="line"><span style="color: #CE9178">    corresponding physical interface). These will look like 2 addition interfaces</span></span>
<span class="line"><span style="color: #CE9178">    when showing IP links, with names like &#39;</span><span style="color: #9CDCFE">$MACVLAN_FORMAT</span><span style="color: #CE9178">&#39; for the MAC VLAN</span></span>
<span class="line"><span style="color: #CE9178">    and &#39;</span><span style="color: #9CDCFE">$VLAN_FORMAT</span><span style="color: #CE9178">&#39; for the IP VLAN.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #CE9178">    The third version, -d, deletes all IP configuration for provisioned secondary VNICs</span></span>
<span class="line"><span style="color: #CE9178">    as long as there is no -e option. If one or more optional -e options are present</span></span>
<span class="line"><span style="color: #CE9178">    only the given secondary IP addresses are deconfigured and the remaining configuration</span></span>
<span class="line"><span style="color: #CE9178">    is left as is.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #CE9178">    This script is made to be run periodically to pick up changes in VNIC provisioning</span></span>
<span class="line"><span style="color: #CE9178">    (whether adding or deleting). Note that these IP configuration changes are not</span></span>
<span class="line"><span style="color: #CE9178">    persistent, the script must, at a minimum, be run on each startup.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #CE9178">    -c          Add IP configuration for VNICs that are not configured and delete</span></span>
<span class="line"><span style="color: #CE9178">                for VNICs that are no longer provisioned.</span></span>
<span class="line"><span style="color: #CE9178">    -d          Deconfigure all VNICs (except the primary). If a -e option is also</span></span>
<span class="line"><span style="color: #CE9178">                present only the secondary IP address(es) are deconfigured.</span></span>
<span class="line"><span style="color: #CE9178">    -e &lt;IP address&gt; &lt;VNIC OCID&gt;</span></span>
<span class="line"><span style="color: #CE9178">                Secondary private IP address to configure or deconfigure.</span></span>
<span class="line"><span style="color: #CE9178">    -h          Print help.</span></span>
<span class="line"><span style="color: #CE9178">    -n [&lt;format&gt;]</span></span>
<span class="line"><span style="color: #CE9178">                When configuring, place interfaces in namespace identified by the given</span></span>
<span class="line"><span style="color: #CE9178">                format. Format can include </span><span style="color: #D7BA7D">\$</span><span style="color: #CE9178">nic and </span><span style="color: #D7BA7D">\$</span><span style="color: #CE9178">vltag variables. The name</span></span>
<span class="line"><span style="color: #CE9178">                defaults to &#39;</span><span style="color: #9CDCFE">$DEF_NS_FORMAT_BM</span><span style="color: #CE9178">&#39; for BMs and &#39;</span><span style="color: #9CDCFE">$DEF_NS_FORMAT_VM</span><span style="color: #CE9178">&#39; for VMs.</span></span>
<span class="line"><span style="color: #CE9178">                When configuring multiple VNICs ensure the namespaces are unique.</span></span>
<span class="line"><span style="color: #CE9178">    -q          Suppress information messages.</span></span>
<span class="line"><span style="color: #CE9178">    -r          Start sshd in namespace (if -n is present)</span></span>
<span class="line"><span style="color: #CE9178">    -s          Show information on all provisioning and interface configuration.</span></span>
<span class="line"><span style="color: #CE9178">                This is the default action if no options are given.</span></span>
<span class="line"><span style="color: #CE9178">                Columns:</span></span>
<span class="line"><span style="color: #CE9178">                    CONFIG  &#39;</span><span style="color: #9CDCFE">$ADD</span><span style="color: #CE9178">&#39; indicates missing IP config, &#39;</span><span style="color: #9CDCFE">$DELETE</span><span style="color: #CE9178">&#39; missing VNIC</span></span>
<span class="line"><span style="color: #CE9178">                    ADDR    IP address</span></span>
<span class="line"><span style="color: #CE9178">                    SPREFIX subnet CIDR prefix</span></span>
<span class="line"><span style="color: #CE9178">                    SBITS   subnet mask bits</span></span>
<span class="line"><span style="color: #CE9178">                    VIRTRT  virutal router IP address</span></span>
<span class="line"><span style="color: #CE9178">                    NS      namespace (if any)</span></span>
<span class="line"><span style="color: #CE9178">                    IND     interface index (if BM)</span></span>
<span class="line"><span style="color: #CE9178">                    IFACE   interface (underlying physical if VLAN is also set)</span></span>
<span class="line"><span style="color: #CE9178">                    VLTAG   VLAN tag (if BM)</span></span>
<span class="line"><span style="color: #CE9178">                    VLAN    IP virtual LAN (if any)</span></span>
<span class="line"><span style="color: #CE9178">                    STATE   state of interface</span></span>
<span class="line"><span style="color: #CE9178">                    MAC     MAC address</span></span>
<span class="line"><span style="color: #CE9178">                    VNIC    VNIC object identifier</span></span>
<span class="line"><span style="color: #CE9178">    -v          Verbose information messages.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #CE9178">EXAMPLES</span></span>
<span class="line"><span style="color: #CE9178">    </span><span style="color: #9CDCFE">$THIS</span></span>
<span class="line"><span style="color: #CE9178">        Show all provisioned VNICs and configured IP addresses.</span></span>
<span class="line"><span style="color: #CE9178">    </span><span style="color: #9CDCFE">$THIS</span><span style="color: #CE9178"> -c</span></span>
<span class="line"><span style="color: #CE9178">        Set configuration without a namespace.</span></span>
<span class="line"><span style="color: #CE9178">    </span><span style="color: #9CDCFE">$THIS</span><span style="color: #CE9178"> -c -n &#39;&#39;</span></span>
<span class="line"><span style="color: #CE9178">        Set configuration using a namespace with the default format.</span></span>
<span class="line"><span style="color: #CE9178">    </span><span style="color: #9CDCFE">$THIS</span><span style="color: #CE9178"> -c -n &#39;myns</span><span style="color: #D7BA7D">\$</span><span style="color: #CE9178">vltag&#39;</span></span>
<span class="line"><span style="color: #CE9178">        Set configuration using a namespace with format &#39;myns</span><span style="color: #D7BA7D">\$</span><span style="color: #CE9178">vltag&#39;.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #CE9178">SEE ALSO:</span></span>
<span class="line"><span style="color: #CE9178">    OCI networking overview including route tables and security lists:</span></span>
<span class="line"><span style="color: #CE9178">        https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/overview.htm</span></span>
<span class="line"><span style="color: #CE9178">    Note: secondary VNIC in different VCN not handled, requires manually adding default route:</span></span>
<span class="line"><span style="color: #CE9178">        ip route add &lt;VCN2 CIDR&gt; via &lt;VCN2 sec VNIC subnet virt router ip&gt; dev &lt;VCN2 sec VNIC ifname&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">EOF</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># TODO secondary private IPs in metadata</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">show</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">config</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">deconfig</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;&#39;</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">os_ver</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$OS_ID</span><span style="color: #CE9178">-</span><span style="color: #9CDCFE">$OS_VERSION</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">os_maj_ver</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$OS_ID</span><span style="color: #CE9178">-</span><span style="color: #9CDCFE">$OS_MAJ_VERSION</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #C586C0">while</span><span style="color: #D4D4D4"> [ </span><span style="color: #569CD6">$#</span><span style="color: #D4D4D4"> -ge </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">declare</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">opt</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$1</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">shift</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">case</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$opt</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span></span>
<span class="line"><span style="color: #D4D4D4">        -c) config=</span><span style="color: #CE9178">&#39;t&#39;</span><span style="color: #D4D4D4">;;</span></span>
<span class="line"><span style="color: #D4D4D4">        -d) deconfig=</span><span style="color: #CE9178">&#39;t&#39;</span><span style="color: #D4D4D4">;;</span></span>
<span class="line"><span style="color: #D4D4D4">        -e) </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #569CD6">$#</span><span style="color: #D4D4D4"> -lt </span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;secondary private IP address option requires &lt;IP address&gt; &lt;VNIC OCID&gt;&quot;</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">SEC_ADDRS</span><span style="color: #D4D4D4">+=(</span><span style="color: #9CDCFE">$1</span><span style="color: #D4D4D4">); </span><span style="color: #DCDCAA">shift</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">SEC_VNICS</span><span style="color: #D4D4D4">+=(</span><span style="color: #9CDCFE">$1</span><span style="color: #D4D4D4">); </span><span style="color: #DCDCAA">shift</span></span>
<span class="line"><span style="color: #D4D4D4">            ;;</span></span>
<span class="line"><span style="color: #D4D4D4">        -n) </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$os_maj_ver</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&quot;ol-6&quot;</span><span style="color: #D4D4D4"> ] || [ </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$os_maj_ver</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&quot;centos-6&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;namespaces not supported on this os version (</span><span style="color: #9CDCFE">$os_ver</span><span style="color: #CE9178">)&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #569CD6">$#</span><span style="color: #D4D4D4"> -ge </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> ] &amp;&amp; ! [[ </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$1</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #D4D4D4">=~</span><span style="color: #D4D4D4"> ^</span><span style="color: #D7BA7D">\-</span><span style="color: #D4D4D4"> ]]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">                [ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$1</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #9CDCFE">NS_FORMAT</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$1</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #DCDCAA">shift</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">USE_NS</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;t&#39;</span><span style="color: #D4D4D4">;;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">-r</span><span style="color: #D4D4D4">) START_SSHD=</span><span style="color: #CE9178">&#39;t&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">            [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$SSHD</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;missing sshd command&quot;</span><span style="color: #D4D4D4">;;</span></span>
<span class="line"><span style="color: #D4D4D4">        -s) show=</span><span style="color: #CE9178">&#39;t&#39;</span><span style="color: #D4D4D4">;;</span></span>
<span class="line"><span style="color: #D4D4D4">        -h) oci_vcn_help; </span><span style="color: #DCDCAA">exit</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">;;</span></span>
<span class="line"><span style="color: #D4D4D4">        -q) </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$DEBUG</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot specify quiet with verbose&quot;</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">QUIET</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;t&#39;</span><span style="color: #D4D4D4">;;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">-v</span><span style="color: #D4D4D4">) </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$QUIET</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot specify verbose with quiet&quot;</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">DEBUG</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;t&#39;</span><span style="color: #D4D4D4">;;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">-*</span><span style="color: #D4D4D4">) oci_vcn_err </span><span style="color: #CE9178">&quot;unknown option </span><span style="color: #9CDCFE">$opt</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">;;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">esac</span></span>
<span class="line"><span style="color: #C586C0">done</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">[ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$START_SSHD</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$USE_NS</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;cannot start sshd if namespace is not created&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">[ </span><span style="color: #9CDCFE">$EUID</span><span style="color: #D4D4D4"> -eq </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;must be run as root&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># read all metadata and ip config</span></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_md_read</span></span>
<span class="line"><span style="color: #DCDCAA">oci_vcn_read</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># process options</span></span>
<span class="line"><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$config</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">    [ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$deconfig</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #DCDCAA">oci_vcn_err</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;conflicting options&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">oci_vcn_config</span></span>
<span class="line"><span style="color: #D4D4D4">    [ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$show</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #DCDCAA">oci_vcn_read</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># reread if show</span></span>
<span class="line"><span style="color: #C586C0">elif</span><span style="color: #D4D4D4"> [ -n </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$deconfig</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ ${#</span><span style="color: #9CDCFE">SEC_ADDRS</span><span style="color: #D4D4D4">[@]} -gt </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># just deconfig addrs</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_config_or_deconfig_sec_addrs</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">else</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># deconfig all</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">oci_vcn_deconfig_all</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">    [ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$show</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #DCDCAA">oci_vcn_read</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># reread if show</span></span>
<span class="line"><span style="color: #C586C0">else</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">show</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&#39;t&#39;</span></span>
<span class="line"><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">[ -z </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$show</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ] || </span><span style="color: #DCDCAA">oci_vcn_show</span></span>
<span class="line"></span></code></pre></div>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Oracle Data Block Recover</title>
		<link>https://furushima.com.br/blog/oracle-data-block-recover/</link>
		
		<dc:creator><![CDATA[Acacio Lima Rocha]]></dc:creator>
		<pubDate>Sat, 27 Sep 2025 17:08:14 +0000</pubDate>
				<category><![CDATA[CDB]]></category>
		<category><![CDATA[Oracle]]></category>
		<guid isPermaLink="false">https://furushima.com.br/?p=2912</guid>

					<description><![CDATA[A recuperação de blocos de dados corrompidos no Oracle Database é uma técnica essencial para garantir a integridade dos dados sem a necessidade de restaurar todo o banco de dados. O Oracle fornece uma funcionalidade topzera para corrigir blocos corrompidos individualmente usando o RMAN, e é possível analisar o conteúdo desses blocos através de dumps [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>A recuperação de blocos de dados corrompidos no Oracle Database é uma técnica essencial para garantir a integridade dos dados sem a necessidade de restaurar todo o banco de dados. O Oracle fornece uma funcionalidade topzera para corrigir blocos corrompidos individualmente usando o <strong>RMAN</strong>, e é possível analisar o conteúdo desses blocos através de dumps para examinar registros específicos.</p>



<p class="has-vivid-red-color has-text-color has-link-color wp-elements-6d5b5a8f143d711856e2bac48efce38c"><strong>⚠️ CONTÉM TEXTO MELHORADO POR AI  &#8211; E TA TUDO BEM (SE SOUBER USAR 🤭)⚠️ </strong></p>



<p>Agora um pouco sobre a arquitetura do data bloco e rowid no Oracle:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img alt="" decoding="async" src="https://acaciolrdba.wordpress.com/wp-content/uploads/2024/10/image.png?w=561" alt="" class="wp-image-944"/><figcaption class="wp-element-caption">Oracle Data Block</figcaption></figure></div>


<h3 class="wp-block-heading">Descrição da Estrutura:</h3>



<ol class="wp-block-list">
<li><strong>Database Block</strong>: O <strong>bloco de dados</strong> é a menor unidade de armazenamento no Oracle. Dentro dele, são armazenados vários pedaços de linha (row pieces), além de informações de controle e metadados que ajudam a gerenciar o armazenamento.</li>



<li><strong>Row Piece</strong>: Um <strong>pedaço de linha</strong> (row piece) é uma parte de uma linha de dados que pode estar completa em um único bloco ou distribuída em vários blocos (chaining ou migration). Ele contém todas as informações relacionadas aos dados da linha.</li>



<li><strong>Row Header</strong>: O <strong>cabeçalho da linha</strong> inclui informações de controle sobre a linha armazenada, como:
<ul class="wp-block-list">
<li><strong>Row Overhead</strong>: Espaço reservado para informações de controle, como status da transação associada à linha e flags de bloqueio.</li>



<li><strong>Number of Columns</strong>: O número de colunas armazenadas na linha.</li>
</ul>
</li>



<li><strong>Column Data</strong>:
<ul class="wp-block-list">
<li><strong>Cluster Key ID (se for clustered)</strong>: Identificação da chave de cluster (caso a tabela faça parte de um cluster).</li>



<li><strong>ROWID of Chained Row Pieces (se houver)</strong>: Se a linha estiver fragmentada em vários blocos, o ROWID (localização da linha) dos outros pedaços de linha será armazenado aqui.</li>



<li><strong>Column Length</strong>: Indica o tamanho de cada coluna.</li>



<li><strong>Column Value</strong>: O valor real da coluna é armazenado nessa parte, onde cada coluna tem seu comprimento e valor específicos.</li>
</ul>
</li>
</ol>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img alt="" decoding="async" src="https://acaciolrdba.wordpress.com/wp-content/uploads/2024/10/dallc2b7e-2024-10-18-15.17.04-a-clean-and-detailed-diagram-of-a-data-structure-representing-an-oracle-rowid-similar-to-the-original-image-provided.-the-image-should-contain-a-line.webp?w=1024" alt="" class="wp-image-948" style="width:696px;height:auto"/><figcaption class="wp-element-caption">Estrutura do ROWID (Representação tosca por AI)</figcaption></figure></div>


<ol class="wp-block-list">
<li><strong>Object ID (OOOOOOO)</strong> &#8211; Representado em vermelho, com 4 bytes de tamanho. Esta parte identifica o objeto no banco de dados (como uma tabela ou índice).</li>



<li><strong>Datafile Number (OBBOFLEBF)</strong> &#8211; Representado em azul, com 1,5 bytes de tamanho. Refere-se ao número do arquivo de dados onde o bloco específico reside.</li>



<li><strong>Block Number (BBBBBB)</strong> &#8211; Representado em verde, com 2,5 bytes de tamanho. Indica o número do bloco dentro do arquivo de dados onde a linha está armazenada.</li>



<li><strong>Row Number (<strong>BBBBBB</strong>R)</strong> &#8211; Representado em preto, com 2 bytes de tamanho. Identifica a linha específica dentro do bloco de dados.</li>
</ol>



<h3 class="wp-block-heading">1. <strong>Identificação de Blocos Corrompidos</strong></h3>



<p>Primeiramente, é necessário identificar os blocos corrompidos no banco de dados. O Oracle mantém uma tabela de sistema chamada <strong>V$DATABASE_BLOCK_CORRUPTION</strong> que lista todos os blocos identificados como corrompidos:</p>



<p>Você pode se atentar ao erro do Oracle:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
ORA-01578: ORACLE data block corrupted (file # X, block # Y)
</pre></div>


<p>Nessa mensagem de erro podemos notar que existe ali o identificador do datafile e do bloco em questão.</p>



<p>Para checar o datafile use a query:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
SELECT file_name
FROM dba_data_files
WHERE file_id = &lt;file#&gt;;
</pre></div>


<p>Para checar o bloco corrompido, pode usar:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
RMAN&gt; BLOCKRECOVER CORRUPION LIST;
SQL&gt; 
COLUMN owner FORMAT A20
COLUMN segment_name FORMAT A30

SELECT DISTINCT owner, segment_name
FROM   v$database_block_corruption dbc
       JOIN dba_extents e ON dbc.file# = e.file_id AND dbc.block# BETWEEN e.block_id and e.block_id+e.blocks-1
ORDER BY 1,2;
</pre></div>


<p>Essa tabela é populada automaticamente após verificações de integridade realizadas por comandos como <code>DBV</code> (Data Block Verifier) ou após erros de leitura durante operações no banco de dados.</p>



<h4 class="wp-block-heading">Outra forma de verificar corrupção de blocos é através de:</h4>



<ul class="wp-block-list">
<li><strong>Alert Log</strong>: mensagens de erro indicando falha de leitura de blocos.</li>



<li><strong>DBVERIFY</strong>: uma ferramenta externa que faz varreduras em datafiles.</li>
</ul>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
dbv file=/path/to/datafile.dbf blocksize=8192
</pre></div>


<h3 class="wp-block-heading">2. <strong>Recuperação de Blocos Corrompidos com RMAN</strong></h3>



<p>Após identificar o(s) bloco(s) corrompido(s), podemos usar o RMAN para a recuperação. O processo pode ser feito enquanto o banco de dados está aberto, reduzindo o tempo de inatividade.</p>



<h4 class="wp-block-heading">Etapas para recuperação:</h4>



<ol class="wp-block-list">
<li><strong>Conectar ao RMAN</strong>:</li>
</ol>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
 rman target /
</pre></div>


<ol start="2" class="wp-block-list">
<li><strong>Executar o comando de recuperação de bloco</strong>: Você pode especificar o arquivo de dados e o número de bloco diretamente:</li>
</ol>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
RMAN&gt; BLOCKRECOVER DATAFILE 4 BLOCK 12345;
</pre></div>


<p>Para recuperar vários blocos de uma vez:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
RMAN&gt; BLOCKRECOVER DATAFILE 4 BLOCK 12345, 12346, 12347;
</pre></div>


<ol start="3" class="wp-block-list">
<li><strong>Verificar se os blocos foram recuperados</strong>: Após a execução do comando <code>BLOCKRECOVER</code>, você pode verificar novamente a visão <strong>V$DATABASE_BLOCK_CORRUPTION</strong> para garantir que os blocos não estão mais corrompidos:</li>
</ol>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
SQL&gt; SELECT * FROM V$DATABASE_BLOCK_CORRUPTION;
</pre></div>


<h3 class="wp-block-heading">3. <strong>Examinando o Conteúdo de Blocos de Dados</strong></h3>



<p>Para entender o conteúdo de um bloco de dados específico, o Oracle oferece um método de &#8220;dumper&#8221; de blocos. Esse procedimento pode ser útil para verificar o que está gravado no bloco, como registros de tabelas.</p>



<h4 class="wp-block-heading">Passos para realizar o dump de um bloco:</h4>



<ol class="wp-block-list">
<li><strong>Identifique o número do bloco, número do arquivo de dados</strong> <strong>e objeto</strong> onde o registro está armazenado. Você pode usar a query abaixo para localizar o arquivo e o número do bloco de uma linha específica:</li>
</ol>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
SQL&gt; SELECT tablespace_name, segment_type, owner, segment_name
        FROM dba_extents
       WHERE file_id = &lt;file#&gt;
         AND &lt;block#&gt; BETWEEN block_id AND block_id + blocks - 1;

SQL&gt; 
COLUMN ROWID FORMAT A18
COLUMN OB_ID FORMAT 99999
COLUMN FILE_ID FORMAT 9
COLUMN BL_NUM FORMAT 99999
COLUMN ROW_NUM FORMAT 99
COLUMN OWNER FORMAT A2
COLUMN OBJECT_NAME FORMAT A9
COLUMN FILE_NAME FORMAT A71
COLUMN FILE_NAME FORMAT A71
COLUMN TABLESPACE_NAME FORMAT A15
SELECT tr.rowid,
       dbms_rowid.rowid_object(tr.rowid) AS OB_ID,
       dbms_rowid.rowid_relative_fno(tr.rowid) AS FILE_ID,
       dbms_rowid.rowid_block_number(tr.rowid) AS BL_NUM,
       dbms_rowid.rowid_row_number(tr.rowid) AS ROW_NUM,
       ob.owner,
       ob.object_name,
       df.file_name,
       df.tablespace_name
  FROM sys.dba_brabo_tb tr
 INNER JOIN dba_objects ob
    ON ob.object_id = dbms_rowid.rowid_object(tr.rowid)
 INNER JOIN dba_data_files df
    ON df.file_id = dbms_rowid.rowid_relative_fno(tr.rowid)
 WHERE tr.dba_brabo_alunos = 666;
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
COLUMN file_id          FORMAT 99999                                                       -- Número do arquivo relativo
COLUMN block_id         FORMAT 9999999                                                     -- Número do bloco no arquivo
COLUMN row_number       FORMAT 99999                                                       -- Número da linha no bloco
COLUMN rows_per_block   FORMAT 99999                                                       -- Total de linhas no bloco
COLUMN rowid            FORMAT A18                                                         -- ROWID do registro
COLUMN file_name        FORMAT A50                                                         -- Nome do arquivo de dados
COLUMN block_size_kb    FORMAT 999999                                                      -- Tamanho do bloco em KB
COLUMN total_blocks     FORMAT 999999                                                      -- Total de blocos
COLUMN segment_name     FORMAT A30                                                         -- Nome do segmento
COLUMN total_rows       FORMAT 99999999                                                    -- Total de linhas estimadas
COLUMN avg_row_length   FORMAT 9999                                                        -- Tamanho médio de uma linha

SELECT 
    A.ROWID AS row_id,                                                                     -- ROWID do registro
    DBMS_ROWID.ROWID_RELATIVE_FNO(A.ROWID) AS file_id,                                     -- Número relativo do arquivo
    DBMS_ROWID.ROWID_BLOCK_NUMBER(A.ROWID) AS block_id,                                    -- Número do bloco no arquivo
    DBMS_ROWID.ROWID_ROW_NUMBER(A.ROWID) AS row_number,                                    -- Número da linha dentro do bloco
    COUNT(*) OVER (PARTITION BY DBMS_ROWID.ROWID_BLOCK_NUMBER(A.ROWID)) AS rows_per_block, -- Total de linhas no bloco
    T.FILE_NAME AS file_name,                                                              -- Nome do arquivo de dados correspondente
    T.BYTES/1024 AS block_size_kb,                                                         -- Tamanho do bloco em KB
    T.BLOCKS AS total_blocks,                                                              -- Total de blocos alocados
    B.SEGMENT_NAME AS segment_name,                                                        -- Nome do segmento associado
    S.NUM_ROWS AS total_rows,                                                              -- Total de linhas estimadas na tabela
    S.AVG_ROW_LEN AS avg_row_length                                                        -- Tamanho médio de uma linha na tabela
FROM 
    DBA_BRABO_TB A
LEFT JOIN 
    DBA_DATA_FILES T
ON 
    T.RELATIVE_FNO = DBMS_ROWID.ROWID_RELATIVE_FNO(A.ROWID)                                -- Relaciona arquivo relativo com DBA_DATA_FILES
LEFT JOIN 
    DBA_SEGMENTS B
ON 
    B.SEGMENT_NAME = 'DBA_BRABO_TB' AND B.OWNER = 'SEU_OWNER'                         -- Ajuste o OWNER conforme necessário
LEFT JOIN 
    DBA_TABLES S
ON 
    S.TABLE_NAME = 'DBA_BRABO_TB' AND S.OWNER = 'SEU_OWNER'                           -- Ajuste o OWNER conforme necessário
WHERE 
    ROWNUM &lt;= 1000
ORDER BY 
    file_id, block_id, row_number;
</pre></div>


<ol start="2" class="wp-block-list">
<li><strong>Usar o comando <code>ALTER SYSTEM DUMP</code> para fazer o dump do bloco</strong>: Para fazer o dump do bloco, utilize o seguinte comando:</li>
</ol>



<p>O comando <code>ALTER SYSTEM DUMP DATAFILE</code> é uma instrução no Oracle que permite extrair informações detalhadas sobre um bloco específico dentro de um arquivo de dados. Essa instrução é usada para diagnosticar problemas de corrupção de bloco, entender a estrutura do bloco, ou obter detalhes sobre os dados contidos em um bloco específico no banco de dados.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
 SQL&gt; ALTER SYSTEM DUMP DATAFILE 4 BLOCK 12345;
</pre></div>


<p>Isso irá gerar um arquivo de dump no diretório de logs do Oracle, geralmente localizado em <code>$ORACLE_HOME/diag</code>.</p>



<ol start="3" class="wp-block-list">
<li><strong>Analisar o arquivo de dump</strong>: O dump contém informações hexadecimais e registros detalhados sobre o conteúdo do bloco. O dump vai incluir cabeçalhos, transações ativas ou inativas, e os dados efetivos gravados nesse bloco.</li>



<li>Isso é coisa antiga, lá pra Oracle 7 e 8, mas ainda funfa. </li>
</ol>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
Dump file /u01/app/oracle/diag/rdbms/dbabrabo/trace/orcl_ora_12345.trc
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
ORACLE_HOME = /u01/app/oracle/product/19.0.0/dbhome_1
System name:    Linux
Node name:      dbabrabo01
Release:        4.18.0-80.el8.x86_64
Version:        #1 SMP Wed Apr 24 11:50:52 EDT 2019
Machine:        x86_64
Instance name: dbabrabo01
Redo thread mounted by this instance: 1
Oracle process number: 45
Unix process pid: 12345, image: oracle@dbabrabo01

*** 2024-10-21 14:35:10.123456 +00:00
*** SESSION ID:(12345.6789) 2024-10-21 14:35:10.123456
*** CLIENT ID:() 2024-10-21 14:35:10.123456
*** SERVICE NAME:(SYS$USERS) 2024-10-21 14:35:10.123456
*** MODULE NAME:(sqlplus@dbabrabo01 (TNS V1-V3)) 2024-10-21 14:35:10.123456
*** ACTION NAME:() 2024-10-21 14:35:10.123456

Start dump data blocks tsn: 4 file#: 4 minblk 12345 maxblk 12345
Block dump from cache:
Dump of buffer cache at level 4 for tsn=4 rdba=16777221

buffer tsn: 4 rdba: 0x01003039 (4/12345)
scn: 0x0000.01234567 seq: 0x01 flg: 0x06 tail: 0x567890ab
frmt: 0x02 chkval: 0xa1d7 type: 0x06=trans data

Block header dump:  0x01003039
 Object id on Block? Y
 seg/obj: 0x456789  csc: 0x00.12345678  itc: 3  flg: O-
  brn: 0  bdba: 0x01003038 ver: 0x01 opc: 0
  inc: 0  exflg: 0

Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0009.001.00001234 0x01800012.3456789f C---    0 scn 0x0000.01234567
0x02 0x0012.002.00004567 0x01800012.345679ab --U-    2 scn 0x0000.01234568
0x03 0x0034.001.00007890 0x01800012.34567abc ----    3 scn 0x0000.01234569

Data Block:
-----------------------------------------------------------------------------
tsiz: 0x1fa0
flag: 0x2
nrid:  0x01003039
col  0: &#x5B; 3]  c1 02 03
col  1: &#x5B; 2]  c1 04
col  2: &#x5B; 4]  c1 05 c1 06
col  3: &#x5B; 8]  c2 01 00 00 00 07 08 09
row#0&#x5B;8018] flag: C
lock: 2
col  0: &#x5B; 2] 80 80
col  1: &#x5B; 6] 80 80 81 81 82 82
col  2: &#x5B; 1] 80
col  3: &#x5B; 3] 00 00 00
</pre></div>


<p>Neste exemplo, o dump mostra o cabeçalho do bloco, identificadores de objetos, o estado de transações e registros de mudanças. Isso pode ser útil em casos onde é necessário analisar a causa da corrupção ou o estado de uma transação em andamento.</p>



<ul class="wp-block-list">
<li><strong><code>Block header dump: 0x010032a8</code></strong>: O cabeçalho do bloco que está sendo &#8220;despejado&#8221;. O valor <code>0x010032a8</code> é o endereço hexadecimal do bloco.</li>



<li><strong><code>Object id on Block? Y</code></strong>: Indica que existe um ID de objeto associado ao bloco (neste caso, &#8220;Y&#8221; para &#8220;Yes&#8221;).</li>



<li><strong><code>seg/obj: 0x19b8</code></strong>: Este é o identificador de segmento ou objeto (ID de objeto 0x19b8).</li>



<li><strong><code>csc: 0x00.2f4c43</code></strong>: Este é o SCN (System Change Number) correspondente ao bloco.</li>



<li><strong><code>itl: 2</code></strong>: Indica o número de <em>interested transaction list</em> (ITL) slots no bloco. Isso significa que até 2 transações podem ser controladas dentro do bloco.</li>



<li><strong><code>Itl Xid Uba Flag Lck Scn/Fsc</code></strong>: Esses são os detalhes das transações ativas no bloco:</li>



<li><strong>Xid</strong>: Transaction ID (ID da transação).</li>



<li><strong>Uba</strong>: Undo Block Address.</li>



<li><strong>Flag</strong>: Flags indicando o status da transação (<code>C</code> indica commit).</li>



<li><strong>Lck</strong>: Lock.</li>



<li><strong>Scn/Fsc</strong>: System Change Number ou Free Space Checkpoint.</li>



<li><strong><code>data_block_dump,data header at 0x7f5f332e900</code></strong>: Início do dump dos dados no bloco. O endereço do cabeçalho de dados começa em <code>0x7f5f332e900</code>.</li>



<li><strong><code>tsiz: 0x1f78</code></strong>: O tamanho do bloco de dados.</li>



<li><strong><code>checksum: 0x39cb</code></strong>: O checksum do bloco, utilizado para garantir a integridade dos dados.</li>
</ul>



<h3 class="wp-block-heading">4. <strong>Recuperação usando Backup Incremental (Opcional)</strong></h3>



<p>Se você não tiver backup de bloco específico ou se o RMAN não conseguir recuperar os blocos por qualquer motivo, você pode usar um backup incremental para recuperar blocos corrompidos:</p>



<ol class="wp-block-list">
<li>Faça um backup incremental do banco de dados:</li>
</ol>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
   RMAN&gt; BACKUP INCREMENTAL LEVEL 1 DATABASE;
</pre></div>


<ol start="2" class="wp-block-list">
<li>Execute a recuperação baseada no backup incremental:</li>
</ol>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
   RMAN&gt; RECOVER BLOCK DATAFILE 4 BLOCK 12345;
</pre></div>


<p>Essa abordagem aplica blocos saudáveis a partir do backup incremental, corrigindo os blocos corrompidos no banco de dados de produção.</p>



<h3 class="wp-block-heading">5. <strong>Verificando a Correção do Bloco</strong></h3>



<p>Após a recuperação, o Oracle realiza automaticamente uma validação para garantir que o bloco foi restaurado corretamente. No entanto, você pode validar manualmente usando o comando:</p>



<p>Versão comum (sem ASM):</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
dbv file=/path/to/datafile.dbf blocksize=8192
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
DBVERIFY: Release 19.0.0.0.0 - Production on Mon Oct 21 14:42:33 2024

Copyright (c) 1982, 2024, Oracle.  All rights reserved.

DBVERIFY - Verification starting : FILE = /path/to/datafile.dbf
DBVERIFY - Verification complete

Total Pages Examined         : 64000
Total Pages Processed (Data) : 32000
Total Pages Failing   (Data) : 0
Total Pages Processed (Index): 16000
Total Pages Failing   (Index): 0
Total Pages Processed (Other): 16000
Total Pages Processed (Seg)  : 0
Total Pages Empty            : 0
Total Pages Marked Corrupt   : 0
Total Pages Influx           : 0
Highest block SCN            : 1123456789 (0.1123456789)

</pre></div>


<p>Versão do ASM:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
dbv USERID=SYS/***** file=+DATAC1/datafiles/users01.dbf logfile=/tmp/dbv_dbabrabo.log
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
DBVERIFY: Release 19.0.0.0.0 - Production on Mon Oct 21 15:35:12 2024

Copyright (c) 1982, 2024, Oracle.  All rights reserved.

DBVERIFY - Verification starting : FILE = +DATAC1/datafiles/users01.dbf
DBVERIFY - Verification complete

Total Pages Examined         : 32000
Total Pages Processed (Data) : 16000
Total Pages Failing   (Data) : 0
Total Pages Processed (Index): 8000
Total Pages Failing   (Index): 0
Total Pages Processed (Other): 8000
Total Pages Empty            : 0
Total Pages Marked Corrupt   : 0
Total Pages Influx           : 0
Highest block SCN            : 123456789 (0.123456789)

</pre></div>


<p>Isso garantirá que o bloco foi corrigido sem outros erros.</p>



<h3 class="wp-block-heading">6. <strong><strong>Recuperação de Blocos Corrompidos com <a href="https://docs.oracle.com/en/database/oracle/oracle-database/21/arpls/DBMS_REPAIR.html#GUID-B8EC4AB3-4D6A-46C9-857F-4ED53CD9C948" target="_blank" rel="noreferrer noopener">DBMS_REPAIR</a></strong></strong></h3>



<p><strong>Exemplo oriundos do mestre <a href="https://oracle-base.com/articles/misc/detect-and-correct-corruption" target="_blank" rel="noreferrer noopener">Tim Hall</a></strong></p>



<p>O pacote <strong>DBMS_REPAIR</strong> do Oracle permite identificar e tratar blocos corrompidos no banco de dados. Diferentemente de outros métodos, ele não apenas detecta, mas também permite &#8220;marcar&#8221; blocos danificados para serem ignorados por operações de DML.</p>



<h3 class="wp-block-heading">Criação das Tabelas Administrativas</h3>



<p>Para gerenciar os blocos corrompidos, duas tabelas administrativas devem ser criadas:: uma para armazenar informações dos blocos corrompidos e outra para guardar chaves órfãs de índices.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
BEGIN
  DBMS_REPAIR.admin_tables (
    table_name =&gt; 'TBL_CORRUPCAO',
    table_type =&gt; DBMS_REPAIR.repair_table,
    action     =&gt; DBMS_REPAIR.create_action,
    tablespace =&gt; 'USERS');

  DBMS_REPAIR.admin_tables (
    table_name =&gt; 'CHAVES_ORFAS',
    table_type =&gt; DBMS_REPAIR.orphan_table,
    action     =&gt; DBMS_REPAIR.create_action,
    tablespace =&gt; 'USERS');
END;
/
</pre></div>


<h3 class="wp-block-heading">Verificação de Corrupção na Tabela</h3>



<p>Após a criação das tabelas administrativas, a rotina <strong>CHECK_OBJECT</strong> pode ser usada para verificar a existência de blocos corrompidos em uma tabela específica.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
SET SERVEROUTPUT ON
DECLARE
  v_blocos_corrompidos INT;
BEGIN
  v_blocos_corrompidos := 0;
  DBMS_REPAIR.check_object (
    schema_name       =&gt; 'DBABRABO',
    object_name       =&gt; 'CLIENTES',
    repair_table_name =&gt; 'TBL_CORRUPCAO',
    corrupt_count     =&gt; v_blocos_corrompidos);
  DBMS_OUTPUT.put_line('Blocos corrompidos detectados: ' || TO_CHAR(v_blocos_corrompidos));
END;
/
</pre></div>


<h3 class="wp-block-heading">Marcação de Blocos Corrompidos</h3>



<p>Se houver blocos corrompidos, eles podem ser &#8220;marcados&#8221; para serem ignorados durante as operações de DML.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
SET SERVEROUTPUT ON
DECLARE
  v_blocos_corrigidos INT;
BEGIN
  v_blocos_corrigidos := 0;
  DBMS_REPAIR.fix_corrupt_blocks (
    schema_name       =&gt; 'DBABRABO',
    object_name       =&gt; 'CLIENTES',
    object_type       =&gt; DBMS_REPAIR.table_object,
    repair_table_name =&gt; 'TBL_CORRUPCAO',
    fix_count         =&gt; v_blocos_corrigidos);
  DBMS_OUTPUT.put_line('Blocos marcados como corrompidos: ' || TO_CHAR(v_blocos_corrigidos));
END;
/
</pre></div>


<h3 class="wp-block-heading">Identificação de Chaves Órfãs em Índices</h3>



<p>Após marcar os blocos corrompidos, os índices associados devem ser verificados para identificar chaves órfãs.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
SET SERVEROUTPUT ON
DECLARE
  v_chaves_orfas INT;
BEGIN
  v_chaves_orfas := 0;
  DBMS_REPAIR.dump_orphan_keys (
    schema_name       =&gt; 'DBABRABO',
    object_name       =&gt; 'IDX_CLIENTES',
    object_type       =&gt; DBMS_REPAIR.index_object,
    repair_table_name =&gt; 'TBL_CORRUPCAO',
    orphan_table_name =&gt; 'CHAVES_ORFAS',
    key_count         =&gt; v_chaves_orfas);
  DBMS_OUTPUT.put_line('Chaves órfãs detectadas: ' || TO_CHAR(v_chaves_orfas));
END;
/
</pre></div>


<p>Caso existam chaves órfãs, o índice deve ser reconstruído para corrigir o problema.</p>



<h3 class="wp-block-heading">Reconstrução das Freelists</h3>



<p>Os blocos marcados como corrompidos são removidos automaticamente das freelists. Contudo, isso pode causar problemas de acesso aos blocos seguintes, sendo necessário reconstruir as freelists.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
BEGIN
  DBMS_REPAIR.rebuild_freelists (
    schema_name =&gt; 'DBABRABO',
    object_name =&gt; 'CLIENTES',
    object_type =&gt; DBMS_REPAIR.table_object);
END;
/
</pre></div>


<h3 class="wp-block-heading">Ignorar Blocos Corrompidos</h3>



<p>Para garantir que os blocos corrompidos sejam ignorados durante operações de DML, utilize a rotina <strong>SKIP_CORRUPT_BLOCKS</strong>.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
BEGIN
  DBMS_REPAIR.skip_corrupt_blocks (
    schema_name =&gt; 'DBABRABO',
    object_name =&gt; 'CLIENTES',
    object_type =&gt; DBMS_REPAIR.table_object,
    flags       =&gt; DBMS_REPAIR.skip_flag);
END;
/
</pre></div>


<h3 class="wp-block-heading">BONUS- <strong>BBED</strong> (Para você brincar no seu LAB[APENAS])</h3>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
                             ______
                          .-&quot;      &quot;-.
                         /            \
             _          |              |          _
            ( \         |,  .-.  .-.  ,|         / )
             &gt; &quot;=._     | )(__/  \__)( |     _.=&quot; &lt;
            (_/&quot;=._&quot;=._ |/     /\     \| _.=&quot;_.=&quot;\_)
                   &quot;=._ (_     ^^     _)&quot;_.=&quot;
                       &quot;=\__|IIIIII|__/=&quot;
                      _.=&quot;| \IIIIII/ |&quot;=._
            _     _.=&quot;_.=&quot;\          /&quot;=._&quot;=._     _
           ( \_.=&quot;_.=&quot;     `--------`     &quot;=._&quot;=._/ )
            &gt; _.=&quot;                            &quot;=._ &lt;
           (_/                                    \_)
</pre></div>


<p>O utilitário <strong>BBED</strong> (Block Browser and Editor) é uma ferramenta interna do Oracle que permite visualizar e modificar blocos de dados em nível físico. No entanto, a Oracle não suporta oficialmente o BBED para uso em produção, pois ele pode ser muito perigoso se utilizado incorretamente, uma vez que permite a modificação de blocos no nível mais baixo, o que pode corromper dados se usado de maneira imprudente.</p>



<p>Dito isso, aqui está uma visão geral e exemplos de como você pode usar o <strong>BBED</strong> para <strong>recuperação de blocos corrompidos</strong> em Oracle. O BBED não é distribuído por padrão, mas pode ser construído a partir do Oracle Binary. Vou incluir os passos para configurá-lo e alguns exemplos de uso.</p>



<h3 class="wp-block-heading">1. Preparando o BBED:</h3>



<ol class="wp-block-list">
<li><strong>Verifique se o BBED está disponível no seu ambiente Oracle</strong>. Muitas vezes ele é desabilitado, mas você pode ativá-lo se encontrar o binário.</li>
</ol>



<ul class="wp-block-list">
<li>O executável BBED geralmente pode ser encontrado em <code>$ORACLE_HOME/rdbms/admin/bbed.par</code> e <code>$ORACLE_HOME/rdbms/admin/bbedus.msb</code>.</li>
</ul>



<ol class="wp-block-list">
<li><strong>Copiar e compilar o BBED:</strong></li>
</ol>



<ul class="wp-block-list">
<li>Copie o arquivo <code>bbed</code> para algum diretório de trabalho.</li>



<li>Garanta que os arquivos <code>bbed.par</code> e <code>bbedus.msb</code> estejam no mesmo diretório do binário <code>bbed</code>.</li>



<li>Conceda permissões de execução ao binário: <code>chmod +x bbed</code></li>
</ul>



<ol class="wp-block-list">
<li><strong>Crie um arquivo de parâmetros (<code>bbed.par</code>):</strong><br>O arquivo de parâmetros é necessário para fornecer informações sobre o tamanho do bloco, arquivo de dados, e outros detalhes. Exemplo do conteúdo do <code>bbed.par</code>:</li>
</ol>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
   blocksize=8192
   listfile=/tmp/datafiles.lst
   mode=edit
</pre></div>


<ol start="4" class="wp-block-list">
<li><strong>Arquivo de lista (<code>datafiles.lst</code>)</strong>:<br>Crie um arquivo de lista de datafiles que deseja abrir com o BBED.</li>
</ol>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
   /path/to/datafile1.dbf
   /path/to/datafile2.dbf
</pre></div>


<p>Agora o <strong>BBED</strong> está configurado e pronto para ser usado.</p>



<h3 class="wp-block-heading">2. Comandos básicos de BBED:</h3>



<p>Vamos a alguns exemplos de comandos básicos para recuperação de blocos.</p>



<h4 class="wp-block-heading">2.1. Carregar o BBED e acessar um bloco:</h4>



<ol class="wp-block-list">
<li><strong>Iniciar o BBED:</strong></li>
</ol>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
   $ bbed parfile=/path/to/bbed.par
</pre></div>


<p>Isso carrega o BBED e o arquivo de parâmetros especificado.</p>



<ol start="2" class="wp-block-list">
<li><strong>Abrir um bloco específico:</strong> Para navegar e visualizar um bloco específico no datafile, você precisa acessar o datafile e o número do bloco que deseja inspecionar.</li>
</ol>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
   BBED&gt; set dba 4,12345
</pre></div>


<p>Onde <code>4</code> é o número do datafile, e <code>12345</code> é o número do bloco.</p>



<ol start="3" class="wp-block-list">
<li><strong>Listar os dados do bloco:</strong> Após definir o DBA, você pode visualizar o conteúdo do bloco:</li>
</ol>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
   BBED&gt; map
</pre></div>


<p>Esse comando mostra um mapeamento geral do bloco, como o cabeçalho do bloco, as transações em andamento, e outros metadados.</p>



<ol start="4" class="wp-block-list">
<li><strong>Listar o conteúdo do bloco:</strong> Para exibir o conteúdo do bloco em formato hexadecimal, você pode usar o comando <code>dump</code>.</li>
</ol>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
   BBED&gt; dump
</pre></div>


<p>Esse comando exibe o conteúdo do bloco como uma lista de dados hexadecimais e ASCII. Você pode usar isso para analisar os dados corrompidos ou entender o estado atual do bloco.</p>



<h4 class="wp-block-heading">2.2. Exemplo de recuperação de bloco corrompido:</h4>



<p>Vamos supor que você tenha identificado que o bloco está corrompido e precise alterá-lo para recuperá-lo.</p>



<ol class="wp-block-list">
<li><strong>Identificar a corrupção:</strong><br>Ao visualizar o bloco, você pode verificar se há campos corrompidos ou inválidos. Suponhamos que o cabeçalho do bloco esteja corrompido.</li>



<li><strong>Editar o cabeçalho do bloco:</strong> O campo do cabeçalho do bloco pode ser editado diretamente. Suponha que você precise ajustar o campo <code>kcbh.seq</code> (sequência do cabeçalho de bloco). Você pode ajustar isso manualmente. Primeiro, localize o deslocamento (<code>offset</code>) do campo <code>kcbh.seq</code>.</li>
</ol>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
   BBED&gt; p kcbh.seq
</pre></div>


<p>Isso imprime o valor atual do campo <code>kcbh.seq</code>. Agora, se ele estiver incorreto, você pode corrigir o valor:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
   BBED&gt; modify /x 0004 at kcbh.seq
</pre></div>


<p>Isso altera o valor do campo para <code>0004</code>.</p>



<ol start="3" class="wp-block-list">
<li><strong>Salvar as alterações:</strong> Uma vez que você fez a modificação, você pode gravar o bloco de volta no datafile.</li>
</ol>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
   BBED&gt; sum
   BBED&gt; write
</pre></div>


<p>O comando <code>sum</code> calcula o checksum do bloco modificado, e <code>write</code> grava o bloco de volta no arquivo de dados.</p>



<h3 class="wp-block-heading">3. Se liga aqui Zé Ruela:</h3>



<ul class="wp-block-list">
<li><strong>BBED é extremamente perigoso</strong>: Uma única modificação incorreta pode corromper permanentemente os dados do seu banco de dados. Sempre faça um backup completo antes de usar esta ferramenta.</li>



<li><strong>A ferramenta não é documentada oficialmente</strong>: A Oracle não oferece suporte ao BBED, e ele deve ser usado apenas em casos extremos ou em ambientes de teste.</li>
</ul>



<p>Embora o <strong>BBED</strong> possa ser uma ferramenta útil para análise em profundidade e modificação de blocos físicos de dados, ele deve ser usado com extremo cuidado e preferencialmente em ambientes de teste. Em produção, a Oracle oferece alternativas mais seguras e suportadas, como o RMAN e o DBMS_REPAIR, para recuperação de blocos corrompidos.</p>



<h2 class="wp-block-heading">Considerações Finais</h2>



<p>A recuperação de blocos de dados do Oracle é uma funcionalidade extremamente útil que evita downtime prolongado e a necessidade de restauração completa. Além disso, a capacidade de fazer dumps de blocos pode ser usada para análise forense, ajudando na resolução de problemas críticos de integridade de dados.</p>



<h3 class="wp-block-heading">Dicas Importantes:</h3>



<ul class="wp-block-list">
<li>Sempre mantenha backups atualizados.</li>



<li>Verifique periodicamente se há corrupção de blocos, utilizando ferramentas como <strong>DBVERIFY e RMAN</strong>.</li>



<li>Sempre utilize procedimentos e padrões com base na documentação, consulte o suporte.</li>



<li>Teste e pratique cenários extremos para saber como contornar crises. </li>



<li>Automatize a verificação e recuperação de blocos corrompidos com RMAN para minimizar o tempo de inatividade.</li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>SQL Server &#8211; PowerShell para Exportação e Importação com BCP</title>
		<link>https://furushima.com.br/blog/sql-server-powershell-para-exportacao-e-importacao-com-bcp/</link>
		
		<dc:creator><![CDATA[Acacio Lima Rocha]]></dc:creator>
		<pubDate>Sat, 27 Sep 2025 16:52:44 +0000</pubDate>
				<category><![CDATA[Banco De Dados]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">https://furushima.com.br/?p=2909</guid>

					<description><![CDATA[Salve, Salve rapaziada, bora de SQL Server hoje? 👀 Como todo bom DBAs, frequentemente nos deparamos com a necessidade de realizar operações de exportação e importação de dados entre bancos (Seja ele Oracle, SQL Server, MySQL etc). Essas tarefas, quando feitas manualmente, são propensas a erros e consomem um tempinho valioso. Pensando nisso, desenvolvi dois [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Salve, Salve rapaziada, bora de SQL Server hoje? 👀</p>



<p>Como todo bom DBAs, frequentemente nos deparamos com a necessidade de realizar operações de exportação e importação de dados entre bancos (Seja ele Oracle, SQL Server, MySQL etc). <br><br>Essas tarefas, quando feitas manualmente, são propensas a erros e consomem um tempinho valioso. Pensando nisso, desenvolvi dois scripts PowerShell que automatiza o processo usando o utilitário&nbsp;<strong>BCP</strong>&nbsp;(Bulk Copy Program).</p>



<p class="has-vivid-red-color has-text-color has-link-color wp-elements-97f38820eb6ad89bfb13592df938e187"><strong>⚠️ CONTÉM TEXTO MELHORADO POR AI – E TA TUDO BEM (SE SOUBER USAR 🤭)⚠️</strong></p>



<p>Coisa simples e rapida aqui:</p>



<h2 class="wp-block-heading">O Script de Exportação</h2>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: powershell; title: ; notranslate">
# Autor: Acaciolr-DBA - DBA BRABO
# Timestamp: 2025-09-25 15:49:06
# Descrição: Script PowerShell para realizar export com bcp.
#

# --- OPÇÕES DE NOMENCLATURA DISPONÍVEIS ---

&lt;#
EXEMPLOS DE NOMES GERADOS COM ESTE SCRIPT:

Formato atual (com data):
BFSQLPROD05_EGuardian_dbo_Usuarios_20250925.txt

Para usar outros formatos, substitua a linha do $FileName por uma das opções abaixo:

# Sem data (básico):
$FileName = &quot;$($ServerName)_$($DatabaseName)_$($SchemaName)_$($TableName).txt&quot;

# Com timestamp completo (data e hora):
$Timestamp = Get-Date -Format &quot;yyyyMMdd_HHmmss&quot;
$FileName = &quot;$($ServerName)_$($DatabaseName)_$($SchemaName)_$($TableName)_$Timestamp.txt&quot;

# Formato curto (sem servidor):
$FileName = &quot;$($DatabaseName)_$($SchemaName)_$($TableName)_$DateStamp.txt&quot;

# Apenas tabela com data:
$FileName = &quot;$($TableName)_$DateStamp.txt&quot;
#&gt;

# --- 1. CONFIGURAÇÕES INICIAIS ---

# Defina as variáveis de conexão e do export
$ServerName = &quot;SQLDBABRABO&quot;                     # Nome da instância do SQL Server
$DatabaseName = &quot;dbabraboDB&quot;                     # &lt;&lt; ATUALIZE ESTE VALOR &gt;&gt; Nome do banco de dados
$SchemaName = &quot;dbo&quot;                             # Nome do schema (geralmente &quot;dbo&quot;)
$TableName = &quot;TB_OCORRENCIAS_CLIENTE_OLD&quot;                       # &lt;&lt; ATUALIZE ESTE VALOR &gt;&gt; Nome da tabela a ser exportada
$OutputPath = &quot;C:\Temp\Export&quot;                  # Caminho para a pasta onde o arquivo será salvo
$Delimiter = &quot;|&quot;                                # Delimitador de campo (vírgula, ponto e vírgula, etc.)

# --- 2. GERAÇÃO AUTOMÁTICA DO NOME DO ARQUIVO ---

# Gera timestamp para incluir no nome do arquivo
$DateStamp = Get-Date -Format &quot;yyyyMMdd&quot;

# Gera o nome do arquivo automaticamente: servidor_database_schema_tabela_data.txt
$FileName = &quot;$($ServerName)_$($DatabaseName)_$($SchemaName)_$($TableName)_$DateStamp.txt&quot;

Write-Host &quot;Nome do arquivo gerado automaticamente: $FileName&quot; -ForegroundColor Cyan
Write-Host &quot;Padrão: &#x5B;SERVIDOR]_&#x5B;DATABASE]_&#x5B;SCHEMA]_&#x5B;TABELA]_&#x5B;DATA].txt&quot; -ForegroundColor Gray

# --- 3. VERIFICAÇÃO E PREPARAÇÃO ---

# Cria o caminho de saída se ele não existir
if (-not (Test-Path $OutputPath)) {
    Write-Host &quot;Caminho de saída '$OutputPath' não existe. Criando...&quot; -ForegroundColor Yellow
    New-Item -ItemType Directory -Path $OutputPath | Out-Null
}

$ExportFilePath = Join-Path -Path $OutputPath -ChildPath $FileName

# Exclui o arquivo anterior se ele existir
if (Test-Path $ExportFilePath) {
    Write-Host &quot;Arquivo existente '$ExportFilePath' será substituído.&quot; -ForegroundColor Yellow
    Remove-Item -Path $ExportFilePath -Force | Out-Null
}

# --- 4. EXECUÇÃO DO BCP ---

# A sintaxe do comando bcp:
# bcp &lt;database_name&gt;.&lt;schema_name&gt;.&lt;table_name&gt; out &lt;data_file&gt; -S &lt;server_name&gt; -T -t &lt;delimiter&gt; -c

# Parâmetros do BCP:
# out: indica que os dados serão exportados da tabela para um arquivo.
# -S: especifica o nome da instância do SQL Server.
# -T: usa a autenticação confiável (Windows Authentication). Para autenticação SQL, use -U e -P.
# -t: especifica o delimitador de campo.
# -c: usa modo de caractere. Se preferir modo nativo, use -n.

Write-Host &quot;Iniciando export da tabela '$TableName'...&quot; -ForegroundColor Green
Write-Host &quot;Arquivo de destino: $ExportFilePath&quot; -ForegroundColor Cyan

$bcpCommand = &quot;bcp &#x5B;$DatabaseName].&#x5B;$SchemaName].&#x5B;$TableName] out `&quot;$ExportFilePath`&quot; -S $ServerName -T -t`&quot;$Delimiter`&quot; -c&quot;

# Executa o comando bcp
Invoke-Expression $bcpCommand

# --- 5. VERIFICAÇÃO DO RESULTADO ---

# Verifica se o arquivo foi criado e tem conteúdo
if (Test-Path $ExportFilePath) {
    $fileSize = (Get-Item $ExportFilePath).Length
    
    if ($fileSize -gt 0) {
        Write-Host &quot;Export concluído com sucesso!&quot; -ForegroundColor Green
        Write-Host &quot;Arquivo salvo em: $ExportFilePath&quot; -ForegroundColor Cyan
        
        # Condicional - MB se for grande, KB se for pequeno
        if ($fileSize -gt 1MB) {
            Write-Host &quot;Tamanho do arquivo: $(&#x5B;math]::Round($fileSize / 1MB, 2)) MB&quot; -ForegroundColor Yellow
        } else {
            Write-Host &quot;Tamanho do arquivo: $(&#x5B;math]::Round($fileSize / 1KB, 2)) KB&quot; -ForegroundColor Yellow
        }
        
        # Informações adicionais sobre o arquivo gerado
        Write-Host &quot;Data do export: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')&quot; -ForegroundColor Gray
        
    } else {
        Write-Host &quot;O arquivo foi criado, mas está vazio. Verifique se a tabela tem dados ou se ocorreu algum erro na execução.&quot; -ForegroundColor Red
    }
} else {
    Write-Host &quot;ERRO: O arquivo '$ExportFilePath' não foi criado. Verifique as permissões de acesso ou o comando bcp.&quot; -ForegroundColor Red
}
</pre></div>

<div class="wp-block-image">
<figure class="aligncenter size-large"><img alt="" decoding="async" src="https://acaciolrdba.wordpress.com/wp-content/uploads/2025/09/image-1.png?w=850" alt="" class="wp-image-1622"/></figure></div>


<h2 class="wp-block-heading">Características Principais</h2>



<p>O script de exportação foi projetado para ser&nbsp;<strong>eficiente</strong>, incluindo:</p>



<ul class="wp-block-list">
<li><strong>Nomenclatura automática</strong>: Gera nomes de arquivos seguindo o padrão&nbsp;<code>Servidor_Database_Schema_Tabela_Data.txt</code></li>



<li><strong>Verificação de integridade</strong>: Confirma a criação do arquivo e valida seu tamanho</li>



<li><strong>Flexibilidade de delimitadores</strong>: Suporta qualquer caractere como separador (padrão: pipe&nbsp;<code>|</code>)</li>



<li><strong>Autenticação Windows</strong>: Usa credenciais integradas para segurança</li>
</ul>



<h3 class="wp-block-heading">Como Funciona</h3>



<p>O script automaticamente:</p>



<ol start="1" class="wp-block-list">
<li>Cria o diretório de destino se não existir</li>



<li>Remove arquivos anteriores com o mesmo nome</li>



<li>Executa o BCP com os parâmetros otimizados</li>



<li>Fornece um relatório detalhado do resultado</li>
</ol>



<h2 class="wp-block-heading">O Script de Importação</h2>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: powershell; title: ; notranslate">
# Autor: Acaciolr-DBA - DBA BRABO
# Timestamp: 2025-09-25 15:49:06
# Descrição: Script PowerShell para realizar import com bcp.
#

# --- 1. CONFIGURAÇÕES INICIAIS ---

# Defina as variáveis de conexão e do import
$ServerName = &quot;SQLDBABRABO&quot;                     # Nome da instância do SQL Server
$DatabaseName = &quot;dbabraboDB&quot;                     # &lt;&lt; ATUALIZE ESTE VALOR &gt;&gt; Nome do banco de dados
$SchemaName = &quot;dbo&quot;                                                             # Nome do schema (geralmente &quot;dbo&quot;)
$TableName = &quot;TB_OCORRENCIAS_CLIENTE_NEW&quot;                                       # &lt;&lt; ATUALIZE ESTE VALOR &gt;&gt; Nome da tabela de destino
$InputPath = &quot;C:\Temp\Export&quot;                                                   # Caminho para a pasta onde o arquivo está localizado
$FileName = &quot;BFSQLPROD05_EGuardian_dbo_TB_OCORRENCIAS_CLIENTE_20250925.txt&quot;     # Nome do arquivo de entrada (removido espaço no início)
$Delimiter = &quot;|&quot;                                                                # Delimitador de campo (vírgula, ponto e vírgula, etc.)
$ImportMode = &quot;REPLACE&quot;                                                          # APPEND (adicionar) ou REPLACE (substituir dados)

# Configurações adicionais
$FirstRow = 1                                                                   # Primeira linha a importar (2 se tem cabeçalho, 1 se não tem)
$BatchSize = 1000                                                               # Tamanho do lote para processamento
$ErrorFile = &quot;C:\Temp\Import_Errors.txt&quot;                                        # Arquivo para registrar erros

# --- 2. VERIFICAÇÃO E PREPARAÇÃO ---

$ImportFilePath = Join-Path -Path $InputPath -ChildPath $FileName

# Verifica se o arquivo de entrada existe
if (-not (Test-Path $ImportFilePath)) {
    Write-Host &quot;ERRO: O arquivo de entrada '$ImportFilePath' não foi encontrado!&quot; -ForegroundColor Red
    exit 1
}

# Verifica o tamanho do arquivo
$fileSize = (Get-Item $ImportFilePath).Length
Write-Host &quot;Arquivo de entrada encontrado: $ImportFilePath&quot; -ForegroundColor Green
Write-Host &quot;Tamanho do arquivo: $(&#x5B;math]::Round($fileSize / 1MB, 2)) MB&quot; -ForegroundColor Cyan

# Cria diretório para arquivo de erro se não existir
$ErrorDir = Split-Path $ErrorFile -Parent
if (-not (Test-Path $ErrorDir)) {
    New-Item -ItemType Directory -Path $ErrorDir -Force | Out-Null
}

# Remove arquivo de erro anterior
if (Test-Path $ErrorFile) {
    Remove-Item $ErrorFile -Force
}

# --- 3. PREPARAÇÃO DA TABELA (SE NECESSÁRIO) ---

if ($ImportMode -eq &quot;REPLACE&quot;) {
    Write-Host &quot;Modo REPLACE ativado. Truncando tabela de destino...&quot; -ForegroundColor Yellow
    
    $truncateCommand = @&quot;
sqlcmd -S $ServerName -d $DatabaseName -E -Q &quot;TRUNCATE TABLE &#x5B;$SchemaName].&#x5B;$TableName]&quot;
&quot;@
    
    try {
        Invoke-Expression $truncateCommand
        Write-Host &quot;Tabela truncada com sucesso.&quot; -ForegroundColor Green
    } catch {
        Write-Host &quot;ERRO ao truncar tabela: $($_.Exception.Message)&quot; -ForegroundColor Red
        exit 1
    }
}

# --- 4. VERIFICAÇÃO DA ESTRUTURA DA TABELA ---

Write-Host &quot;Verificando estrutura da tabela de destino...&quot; -ForegroundColor Cyan

$checkTableCommand = @&quot;
sqlcmd -S $ServerName -d $DatabaseName -E -Q &quot;SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '$SchemaName' AND TABLE_NAME = '$TableName' ORDER BY ORDINAL_POSITION&quot; -h-1
&quot;@

try {
    $tableStructure = Invoke-Expression $checkTableCommand
    Write-Host &quot;Estrutura da tabela verificada.&quot; -ForegroundColor Green
    # Opcional: exibir estrutura
    # Write-Host $tableStructure
} catch {
    Write-Host &quot;AVISO: Não foi possível verificar a estrutura da tabela.&quot; -ForegroundColor Yellow
}

# --- BACKUP DA TABELA ORIGINAL COM DATA ---
Write-Host &quot;`n--- CRIANDO BACKUP DA TABELA ORIGINAL ---&quot; -ForegroundColor Yellow

# Extrai o nome original da tabela removendo &quot;_BKP&quot; do final (se existir)
if ($TableName -like &quot;*_BKP&quot;) {
    $OriginalTableName = $TableName -replace &quot;_BKP$&quot;, &quot;&quot;
} else {
    $OriginalTableName = $TableName
}

$BackupSuffix = &quot;_BKP_$(Get-Date -Format 'yyyyMMdd_HHmmss')&quot;  # Sufixo com data/hora
$BackupTableName = $OriginalTableName + $BackupSuffix

Write-Host &quot;Tabela original: $OriginalTableName&quot; -ForegroundColor Cyan
Write-Host &quot;Tabela de backup: $BackupTableName&quot; -ForegroundColor Cyan

# Comando SQL para criar a tabela de backup (apenas estrutura)
$backupCommand = @&quot;
sqlcmd -S $ServerName -d $DatabaseName -E -Q &quot;
SELECT * 
INTO &#x5B;$SchemaName].&#x5B;$BackupTableName] 
FROM &#x5B;$SchemaName].&#x5B;$OriginalTableName];
&quot;
&quot;@

try {
    Write-Host &quot;Criando estrutura da tabela de backup...&quot; -ForegroundColor Cyan
    Invoke-Expression $backupCommand
    Write-Host &quot;Tabela de backup criada com sucesso: $BackupTableName&quot; -ForegroundColor Green
} catch {
    Write-Host &quot;ERRO ao criar backup da tabela: $($_.Exception.Message)&quot; -ForegroundColor Red
    # Decide se quer continuar ou parar o script
    # exit 1  # Descomente se quiser parar o script em caso de erro
}

# --- VERIFICAÇÃO DO BACKUP ---
Write-Host &quot;Verificando a tabela de backup criada...&quot; -ForegroundColor Cyan

$verifyBackupCommand = @&quot;
sqlcmd -S $ServerName -d $DatabaseName -E -Q &quot;
SELECT 
    TABLE_NAME,
    TABLE_TYPE,
    TABLE_SCHEMA
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME = '$BackupTableName'
AND TABLE_SCHEMA = '$SchemaName';
&quot; -h-1
&quot;@

try {
    $backupVerification = Invoke-Expression $verifyBackupCommand
    if ($backupVerification -match $BackupTableName) {
        Write-Host &quot;✓ Backup verificado com sucesso: $BackupTableName&quot; -ForegroundColor Green
    } else {
        Write-Host &quot;✗ A tabela de backup não foi encontrada.&quot; -ForegroundColor Red
    }
} catch {
    Write-Host &quot;Erro na verificação do backup: $($_.Exception.Message)&quot; -ForegroundColor Yellow
}

# --- 5. EXECUÇÃO DO BCP IMPORT ---

# A sintaxe do comando bcp para import:
# bcp &lt;database_name&gt;.&lt;schema_name&gt;.&lt;table_name&gt; in &lt;data_file&gt; -S &lt;server_name&gt; -E -t &lt;delimiter&gt; -c -F &lt;first_row&gt; -b &lt;batch_size&gt; -e &lt;error_file&gt;

# Parâmetros do BCP para import:
# in: indica que os dados serão importados do arquivo para a tabela.
# -S: especifica o nome da instância do SQL Server.
# -E: usa a autenticação confiável (Windows Authentication). Para autenticação SQL, use -U &lt;username&gt; -P &lt;password&gt;.
# -t: especifica o delimitador de campo.
# -c: usa modo de caractere.
# -F: especifica a primeira linha a ser importada (útil para pular cabeçalhos).
# -b: especifica o tamanho do lote.
# -e: especifica o arquivo para registrar erros.

Write-Host &quot;Iniciando import para a tabela '$TableName'...&quot; -ForegroundColor Yellow
Write-Host &quot;Primeira linha a importar: $FirstRow&quot; -ForegroundColor Cyan
Write-Host &quot;Tamanho do lote: $BatchSize&quot; -ForegroundColor Cyan

$bcpCommand = &quot;bcp &#x5B;$DatabaseName].&#x5B;$SchemaName].&#x5B;$TableName] in `&quot;$ImportFilePath`&quot; -S $ServerName -T -t`&quot;$Delimiter`&quot; -c -F$FirstRow -b$BatchSize -e`&quot;$ErrorFile`&quot;&quot; 

Write-Host &quot;Comando BCP: $bcpCommand&quot; -ForegroundColor Gray

# Executa o comando bcp e captura o resultado
try {
    $bcpResult = Invoke-Expression $bcpCommand 2&gt;&amp;1
    Write-Host $bcpResult -ForegroundColor White
} catch {
    Write-Host &quot;ERRO durante a execução do BCP: $($_.Exception.Message)&quot; -ForegroundColor Red
}

# --- 6. VERIFICAÇÃO DO RESULTADO ---

Write-Host &quot;`n--- VERIFICAÇÃO DOS RESULTADOS ---&quot; -ForegroundColor Yellow

# Verifica se houve erros
if (Test-Path $ErrorFile) {
    $errorContent = Get-Content $ErrorFile -ErrorAction SilentlyContinue
    if ($errorContent -and $errorContent.Length -gt 0) {
        Write-Host &quot;ATENÇÃO: Erros foram encontrados durante o import!&quot; -ForegroundColor Red
        Write-Host &quot;Arquivo de erros: $ErrorFile&quot; -ForegroundColor Red
        Write-Host &quot;Primeiras linhas dos erros:&quot; -ForegroundColor Red
        $errorContent | Select-Object -First 10 | ForEach-Object { Write-Host &quot;  $_&quot; -ForegroundColor Red }
    } else {
        Write-Host &quot;Nenhum erro registrado.&quot; -ForegroundColor Green
        # Remove arquivo de erro vazio
        Remove-Item $ErrorFile -Force -ErrorAction SilentlyContinue
    }
}

# Conta registros na tabela após o import
Write-Host &quot;Contando registros na tabela de destino...&quot; -ForegroundColor Cyan

$countCommand = @&quot;
sqlcmd -S $ServerName -d $DatabaseName -E -Q &quot;SELECT COUNT(*) as Total_Registros FROM &#x5B;$SchemaName].&#x5B;$TableName]&quot; -h-1
&quot;@

try {
    $recordCount = Invoke-Expression $countCommand
    $recordCount = ($recordCount -replace '\s+', '').Trim()
    Write-Host &quot;Total de registros na tabela: $recordCount&quot; -ForegroundColor Green
} catch {
    Write-Host &quot;Não foi possível contar os registros na tabela.&quot; -ForegroundColor Yellow
}

# Mostra algumas linhas de exemplo (opcional)
Write-Host &quot;`nPrimeiros registros importados:&quot; -ForegroundColor Cyan

$sampleCommand = @&quot;
sqlcmd -S $ServerName -d $DatabaseName -E -Q &quot;SELECT TOP 5 * FROM &#x5B;$SchemaName].&#x5B;$TableName]&quot; -h-1
&quot;@

try {
    $sampleData = Invoke-Expression $sampleCommand
    Write-Host $sampleData -ForegroundColor White
} catch {
    Write-Host &quot;Não foi possível exibir dados de exemplo.&quot; -ForegroundColor Yellow
}

# --- 7. RELATÓRIO FINAL ---

Write-Host &quot;`n=== RELATÓRIO FINAL DO IMPORT ===&quot; -ForegroundColor Green
Write-Host &quot;Servidor: $ServerName&quot; -ForegroundColor Cyan
Write-Host &quot;Banco: $DatabaseName&quot; -ForegroundColor Cyan
Write-Host &quot;Tabela: &#x5B;$SchemaName].&#x5B;$TableName]&quot; -ForegroundColor Cyan
Write-Host &quot;Arquivo importado: $ImportFilePath&quot; -ForegroundColor Cyan
Write-Host &quot;Tamanho do arquivo: $(&#x5B;math]::Round($fileSize / 1MB, 2)) MB&quot; -ForegroundColor Cyan
Write-Host &quot;Modo: $ImportMode&quot; -ForegroundColor Cyan
Write-Host &quot;Delimitador: '$Delimiter'&quot; -ForegroundColor Cyan
Write-Host &quot;Data/Hora: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')&quot; -ForegroundColor Cyan

if (Test-Path $ErrorFile) {
    Write-Host &quot;Arquivo de erros: $ErrorFile&quot; -ForegroundColor Red
} else {
    Write-Host &quot;Import concluído sem erros registrados!&quot; -ForegroundColor Green
}

Write-Host &quot;=== FIM DO RELATÓRIO ===&quot; -ForegroundColor Green

# --- 8. LIMPEZA (OPCIONAL) ---

# Descomente as linhas abaixo se quiser mover o arquivo processado para uma pasta de backup
# $BackupPath = &quot;C:\Temp\Import\Processados&quot;
# if (-not (Test-Path $BackupPath)) { New-Item -ItemType Directory -Path $BackupPath -Force | Out-Null }
# $BackupFile = Join-Path $BackupPath &quot;$(&#x5B;System.IO.Path]::GetFileNameWithoutExtension($FileName))_$(Get-Date -Format 'yyyyMMdd_HHmmss').txt&quot;
# Move-Item $ImportFilePath $BackupFile
# Write-Host &quot;Arquivo movido para: $BackupFile&quot; -ForegroundColor Yellow
</pre></div>

<div class="wp-block-image">
<figure class="aligncenter size-large"><img alt="" decoding="async" src="https://acaciolrdba.wordpress.com/wp-content/uploads/2025/09/image-2.png?w=1024" alt="" class="wp-image-1623"/></figure></div>

<div class="wp-block-image">
<figure class="aligncenter size-large"><img alt="" decoding="async" src="https://acaciolrdba.wordpress.com/wp-content/uploads/2025/09/image-3.png?w=1024" alt="" class="wp-image-1625"/></figure></div>


<h3 class="wp-block-heading">Destaques do Script de Importação</h3>



<p>A versão de importação vai além da simples carga de dados, incorporando&nbsp;<strong>mecanismos de segurança</strong>&nbsp;essenciais:</p>



<ul class="wp-block-list">
<li><strong>Sistema de backup automático</strong>: Cria uma cópia da tabela original antes do import</li>



<li><strong>Dois modos de operação</strong>:&nbsp;<code>APPEND</code>&nbsp;(adiciona dados) ou&nbsp;<code>REPLACE</code>&nbsp;(substitui tabela)</li>



<li><strong>Controle de erros robusto</strong>: Registra e reporta problemas detalhadamente</li>



<li><strong>Validação em múltiplos níveis</strong>: Verifica estrutura, conta registros e exibe amostras</li>
</ul>



<p><strong>Este é o coração da segurança do processo:</strong>&nbsp;antes de qualquer operação, é criado um backup datado da tabela original, permitindo recuperação instantânea em caso de problemas.</p>



<p>Bom rapaziada, fica ai uma dica que achei bacana e importante.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Transportable Tablespace no MySQL &#8211; O Guia Brabo</title>
		<link>https://furushima.com.br/blog/transportable-tablespace-no-mysql-o-guia-brabo/</link>
		
		<dc:creator><![CDATA[Acacio Lima Rocha]]></dc:creator>
		<pubDate>Sat, 27 Sep 2025 16:45:54 +0000</pubDate>
				<category><![CDATA[MySQL]]></category>
		<guid isPermaLink="false">https://furushima.com.br/?p=2903</guid>

					<description><![CDATA[Fala rapaziada, só na boa, na moral, no esquema? espero que sim. Hoje, mais um artigo sobre o danado do bando de dados do golfinho. Vou falar sobre a praticidade do TTS, sim TTS no MySQL (Assim como no Oracle, também existe no MySQL). ⚠️ CONTÉM TEXTO MELHORADO POR AI – E TA TUDO BEM [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Fala rapaziada, só na boa, na moral, no esquema? espero que sim.</p>



<p>Hoje, mais um artigo sobre o danado do bando de dados do golfinho.<br><br>Vou falar sobre a praticidade do TTS, sim TTS no MySQL (Assim como no Oracle, também existe no MySQL).</p>



<p class="has-vivid-red-color has-text-color has-link-color wp-elements-97f38820eb6ad89bfb13592df938e187"><strong><img src="https://s.w.org/images/core/emoji/16.0.1/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> CONTÉM TEXTO MELHORADO POR AI – E TA TUDO BEM (SE SOUBER USAR <img src="https://s.w.org/images/core/emoji/16.0.1/72x72/1f92d.png" alt="🤭" class="wp-smiley" style="height: 1em; max-height: 1em;" />)<img src="https://s.w.org/images/core/emoji/16.0.1/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /></strong></p>



<p>Depois de bater cabeça com a bagaceira acima, bora la.</p>



<h2 class="wp-block-heading"><strong>1. Pré-Requisitos</strong></h2>



<ol class="wp-block-list">
<li>Verificar e ativar a configuração necessária para o Transportable Tablespace funcionar corretamente.</li>



<li>Ter um MySQL <img src="https://s.w.org/images/core/emoji/16.0.1/72x72/1f913.png" alt="🤓" class="wp-smiley" style="height: 1em; max-height: 1em;" /></li>



<li>Ter lido meu artigo anterior sobre <a href="https://acaciolrdba.wordpress.com/2025/03/09/tablespace-no-mysql-%f0%9f%90%ac/" target="_blank" rel="noreferrer noopener">TABLESPACES NO MYSQL</a></li>
</ol>



<p>Esse parça verifica se o InnoDB está configurado para criar um arquivo .ibd separado para cada tabela, o que é essencial para o TTS.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
SHOW VARIABLES LIKE 'innodb_file_per_table';

+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_file_per_table | ON    |
+-----------------------+-------+
</pre></div>


<p><strong>Se precisar ativar:</strong></p>



<p>Ativa o modo file-per-table, permitindo que cada tabela InnoDB tenha seu próprio arquivo de tablespace.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
SET GLOBAL innodb_file_per_table=ON;

Query OK, 0 rows affected (0.01 sec)
</pre></div>


<h2 class="wp-block-heading"><strong>2. Exemplo do esquema</strong></h2>



<h3 class="wp-block-heading"><strong>Na caixa de origem:</strong></h3>



<p>Crie um novo banco de BRABOS (kkkk, foi boa vai) para nossos testes:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
CREATE DATABASE db_brabo;

Query OK, 1 row affected (0.01 sec)
</pre></div>


<p>Selecione o nosso DBzinho recém-criado:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
USE db_brabo;

Database changed
</pre></div>


<p>Então criamos uma tabela para poder simular que temos dados em nosso ambiente super, mega, master, blaster produtivo:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
CREATE TABLE clientes_brabo (
    id INT AUTO_INCREMENT PRIMARY KEY,
    nome VARCHAR(100) NOT NULL,
    email VARCHAR(100) UNIQUE,
    data_cadastro DATETIME DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;

Query OK, 0 rows affected (0.01 sec)
</pre></div>


<p>Vamos adicionar alguns dados de leve:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
INSERT INTO clientes_brabo (nome, email) VALUES 
('Zé Brabo', 'ze@brabo.com'), -- Essa vai pro Marião
('DBA Master', 'dba@brabo.com');

Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0
</pre></div>


<h2 class="wp-block-heading"><strong>3. Processo de Exportação</strong></h2>



<h3 class="wp-block-heading"><strong>Passo 1: Preparação para Exportação</strong></h3>



<p>Esse carinha é&nbsp;<strong>poderoso</strong>&nbsp;e tem um papel crucial quando você quer&nbsp;<strong>mover ou migrar tabelas</strong>&nbsp;no MySQL usando o&nbsp;TTS:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
FLUSH TABLES clientes_brabo FOR EXPORT;

Query OK, 0 rows affected (0.00 sec)
</pre></div>


<p>O que ele faz?</p>



<ol class="wp-block-list">
<li>Trava a tabela para escrita</li>



<li>Finaliza todas as transações pendentes</li>



<li>Cria um arquivo .cfg com os metadados da tabela</li>
</ol>



<h3 class="wp-block-heading"><strong>Passo 2: Localização dos Arquivos</strong></h3>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
ls -l /var/lib/mysql/db_brabo/

-rw-r----- 1 mysql mysql  12345 Jun 10 15:30 clientes_brabo.ibd
-rw-r----- 1 mysql mysql   1024 Jun 10 15:30 clientes_brabo.cfg
</pre></div>


<p>De quais arquivos estamos falando?</p>



<ul class="wp-block-list">
<li>.ibd (arquivo de dados)</li>



<li>.cfg (metadados criados pelo FLUSH TABLES)</li>
</ul>



<h3 class="wp-block-heading"><strong>Passo 3: Cópia de segurança dos arquivos</strong> (se vc é DBA vai entender) </h3>



<p>Copia os arquivos para um local seguro antes de continuar (Não seja juvenil, inferno):</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
cp /var/lib/mysql/db_brabo/clientes_brabo.{ibd,cfg} /backup/
</pre></div>


<h3 class="wp-block-heading"><strong>Passo 4: Liberação da Tabela</strong></h3>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
UNLOCK TABLES;

Query OK, 0 rows affected (0.00 sec)
</pre></div>


<p>Libera a tabela no servidor de origem após a cópia dos arquivos.</p>



<h2 class="wp-block-heading"><strong>4. Processo de Importação</strong></h2>



<h3 class="wp-block-heading"><strong>Passo 1: Preparação do Ambiente de Destino</strong></h3>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
CREATE DATABASE db_brabo_destino;
USE db_brabo_destino;
</pre></div>


<p>Cria e seleciona o banco de dados de destino.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
CREATE TABLE clientes_brabo (
    id INT AUTO_INCREMENT PRIMARY KEY,
    nome VARCHAR(100) NOT NULL,
    email VARCHAR(100) UNIQUE,
    data_cadastro DATETIME DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;

Query OK, 0 rows affected (0.00 sec)

</pre></div>


<p>Recria a mesma estrutura da tabela original, sem dados.</p>



<h3 class="wp-block-heading"><strong>Passo 2: Limpeza do Tablespace Existente</strong></h3>



<p>Remove a tbs vazio recém-criado para preparar a importação.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
ALTER TABLE clientes_brabo DISCARD TABLESPACE;

Query OK, 0 rows affected (0.00 sec)
</pre></div>


<h3 class="wp-block-heading"><strong>Passo 3: Transferência dos Arquivos</strong></h3>



<p>Copia os arquivos para o diretório do MySQL e ajusta as permissões.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
cp /backup/clientes_brabo.{ibd,cfg} /var/lib/mysql/db_brabo_destino/
chown mysql:mysql /var/lib/mysql/db_brabo_destino/clientes_brabo.*
</pre></div>


<h3 class="wp-block-heading"><strong>Passo 4: Importação Final</strong></h3>



<p>Este comando crucial, se liga:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
ALTER TABLE clientes_brabo IMPORT TABLESPACE;

Query OK, 0 rows affected (0.00 sec)
</pre></div>


<p>Sabe o motivo? sei que não <img src="https://s.w.org/images/core/emoji/16.0.1/72x72/1f923.png" alt="🤣" class="wp-smiley" style="height: 1em; max-height: 1em;" />, toma:</p>



<ol class="wp-block-list">
<li>Lê o arquivo .cfg para validar a estrutura</li>



<li>Importa os dados do arquivo .ibd</li>



<li>Reconstroi os índices</li>
</ol>



<h3 class="wp-block-heading"><strong>Passo 5: Verificação</strong></h3>



<p>Bora então checar os dados:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
SELECT * FROM clientes_brabo;

+----+------------+---------------+---------------------+
| id | nome       | email         | data_cadastro       |
+----+------------+---------------+---------------------+
|  1 | Zé Brabo   | ze@brabo.com  | 2023-06-10 15:30:00 |
|  2 | DBA Master | dba@brabo.com | 2023-06-10 15:30:00 |
+----+------------+---------------+---------------------+
</pre></div>


<h2 class="wp-block-heading"><strong>5. Validação</strong> final do esquema</h2>



<p>Bora validar a integridade da tabela:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
CHECK TABLE clientes_brabo;

+-------------------+-------+----------+----------+
| Table             | Op    | Msg_type | Msg_text |
+-------------------+-------+----------+----------+
| db_brabo.clientes | check | status   | OK       |
+-------------------+-------+----------+----------+
</pre></div>


<p><strong>Como boas práticas:</strong></p>



<ol class="wp-block-list">
<li>Sempre verifique a compatibilidade de versões entre as caixas/servers/maquinas etc.</li>



<li>Para tabelas grandes, considere compactar os arquivos durante a transferência</li>



<li>Mantenha backups dos arquivos .ibd e .cfg até confirmar que tudo ocorreu suave na nave.</li>
</ol>



<h2 class="wp-block-heading">Minhas <strong>considerações</strong>: </h2>



<p>Este processo é extremamente útil para:</p>



<ul class="wp-block-list">
<li>Migrações rápidas entre ambientes</li>



<li>Recuperação de tabelas específicas</li>



<li>Criação de ambientes de teste com dados reais</li>
</ul>



<p>Sacou qualé da parada? agora pega teu lab e senta o dedo NELE.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Ficou ruim? Pior que o backup sem binlog? (PQP) <img src="https://s.w.org/images/core/emoji/16.0.1/72x72/1f602.png" alt="😂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
</blockquote>



<p><em>(Brincadeira, tmj! Qualquer coisa, só chamar os BRABO!)</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Tablespace no MySQL 🐬</title>
		<link>https://furushima.com.br/blog/tablespace-no-mysql-%f0%9f%90%ac/</link>
		
		<dc:creator><![CDATA[Acacio Lima Rocha]]></dc:creator>
		<pubDate>Sat, 27 Sep 2025 16:41:52 +0000</pubDate>
				<category><![CDATA[MySQL]]></category>
		<guid isPermaLink="false">https://furushima.com.br/?p=2900</guid>

					<description><![CDATA[Fala rapaziada, so na paz? espero que sim. Hoje vou abordar um assunto simples e pratico que assim como no Oracle, também existe no MySQL, TABLESPACES. ⚠️ CONTÉM TEXTO MELHORADO POR AI – E TA TUDO BEM (SE SOUBER USAR 🤭)⚠️ Essa é nova pra você? ou ja sabia que no MySQL também existe TABLESPACES? [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Fala rapaziada, so na paz? espero que sim.</p>



<p>Hoje vou abordar um assunto simples e pratico que assim como no Oracle, também existe no MySQL, <strong>TABLESPACES</strong>.</p>



<p class="has-vivid-red-color has-text-color has-link-color wp-elements-97f38820eb6ad89bfb13592df938e187"><strong>⚠️ CONTÉM TEXTO MELHORADO POR AI – E TA TUDO BEM (SE SOUBER USAR 🤭)⚠️</strong></p>



<p>Essa é nova pra você? ou ja sabia que no MySQL também existe <strong>TABLESPACES</strong>? </p>



<p>Bom, se é novidade ou não vale dar uma lida para aprender ou relembrar detalhes sobre o assunto.</p>



<p>No MySQL, existem três tipos principais de tablespaces:</p>



<ol start="1" class="wp-block-list">
<li><strong>System Tablespace</strong>: Armazena metadados e dados do sistema.</li>



<li><strong>File-per-Table Tablespace</strong>: Cada tabela é armazenada em seu próprio arquivo&nbsp;<code>.ibd</code> (O que eu acho zoado por ser DBA Oracle kkk).</li>



<li><strong>General Tablespace</strong>: Permite que múltiplas tabelas compartilhem o mesmo arquivo&nbsp;de dados<code> .ibd</code>.</li>
</ol>



<h3 class="wp-block-heading"><strong>Por que usar Tablespaces no MySQL?</strong></h3>



<p>O uso de tablespaces oferece várias vantagens para o DBA desorganizado 🤭:</p>



<ul class="wp-block-list">
<li><strong>Flexibilidade</strong>: Você pode escolher onde armazenar os dados (em um diretório específico, por exemplo).</li>



<li><strong>Desempenho</strong>: Tablespaces permitem otimizar o armazenamento para cenários específicos, como compressão de dados.</li>



<li><strong>Gerenciamento Simplificado</strong>: Facilita a administração de grandes volumes de dados, especialmente em ambientes com múltiplas tabelas.</li>



<li><strong>Compressão</strong>: Tablespaces suportam tabelas comprimidas, reduzindo o uso de espaço em disco.</li>
</ul>



<h3 class="wp-block-heading"><strong>Tipos de Tablespaces no MySQL</strong></h3>



<h4 class="wp-block-heading">1.<strong> System Tablespace</strong></h4>



<p>A System tablespace é o coração do MySQL. Ele armazena metadados do sistema, como o dicionário de dados e os logs de undo. Por padrão, ele é armazenado no arquivo&nbsp;<code>ibdata1</code>. Embora seja essencial para o funcionamento do MySQL, ele não é recomendado para armazenar dados de usuário, pois pode crescer indefinidamente (sim, tem doido pra tudo).</p>



<h4 class="wp-block-heading">2.&nbsp;<strong>File-per-Table Tablespace</strong></h4>



<p>No modo <strong>file-per-table</strong>, cada tabela é armazenada em seu próprio arquivo&nbsp;<code>.ibd</code>. Isso oferece maior flexibilidade, pois você pode mover, copiar ou excluir tabelas individualmente. Além disso, facilita a recuperação de dados em caso de falhas.</p>



<p>Exemplo de criação de uma tabela no modo file-per-table:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
CREATE TABLE tabela_braba (
    cfp INT PRIMARY KEY,
    dba VARCHAR(100)
) ENGINE=InnoDB;
</pre></div>


<h4 class="wp-block-heading">3.&nbsp;<strong>General Tablespace</strong></h4>



<p>General tablespaces permitem que múltiplas tabelas compartilhem o mesmo arquivo&nbsp;<code>.ibd</code>. Eles são ideais para cenários onde você deseja centralizar o armazenamento de várias tabelas ou utilizar compressão de dados.</p>



<p>Suporte aos seguintes row format:</p>



<ul class="wp-block-list">
<li><code>REDUNDANT</code></li>



<li><code>COMPACT</code></li>



<li><code>DYNAMIC</code></li>



<li><code>COMPRESSED</code></li>
</ul>



<p>Exemplo de criação de um general tablespace:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
CREATE TABLESPACE tablespace_braba
ADD DATAFILE '/u01/para/df_brabo_01.ibd'
ENGINE=InnoDB;
</pre></div>


<p>Ou você também pode apenas executar:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
CREATE TABLESPACE tablespace_braba Engine=InnoDB;
</pre></div>


<p>Se a cláusula <strong>ADD DATAFILE</strong> não for especificada ao criar uma tablespace, um datafile com um nome muito louco será criado no lugar (nessa pegada: <em><code><strong>aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee</strong></code></em>).</p>



<p>E para adicionar uma tabela a nova tablespace?</p>



<p>Você pode apenas criar a tabela atribuindo-a sua tablespace:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
CREATE TABLE tabela_braba (
    cfp INT PRIMARY KEY,
    dba VARCHAR(100)
) TABLESPACE tablespace_braba;
</pre></div>


<p>Mas você também pode vincular uma tabela existente a uma tablespace:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
ALTER TABLE tabela_braba TABLESPACE tablespace_braba;
</pre></div>


<p>Podemos validar, verificar e entender a relação tabelas por tablespaces com a consulta:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
SELECT a.NAME AS space_name, b.NAME AS table_name FROM INFORMATION_SCHEMA.INNODB_TABLESPACES a,
       INFORMATION_SCHEMA.INNODB_TABLES b WHERE a.SPACE=b.SPACE AND a.NAME LIKE 'tablespace_braba';
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
+-----------------+--------------------+
| space_name      | table_name         |
+-----------------+--------------------+
| tablespace_braba| teste/tabela_braba |
+-----------------+--------------------+
</pre></div>


<p>Também como no Oracle é possivel adicionar datafiles a essas tablespaces criadas:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
ALTER TABLESPACE tablespace_braba ADD DATAFILE '/u01/oradata/df_brabo_02.ibd' INITIAL_SIZE 48M ENGINE InnoDB;
</pre></div>


<p>Nesse caso acima ja estamos pre-alocando 48M para o arquivo de datafile, mas podemos também adicionar datafile sem alocar espaço previamente, assim:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
ALTER TABLESPACE tablespace_braba ADD DATAFILE '/u01/oradata/df_brabo_03.ibd' ENGINE InnoDB;
</pre></div>


<p>Ainda é possivel também realizar o MOVE das tabelas entre diferentes tipo de tablespaces:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
ALTER TABLE tabela_braba TABLESPACE &#x5B;=] tablespace_name;
ALTER TABLE tabela_braba TABLESPACE &#x5B;=] innodb_system;
ALTER TABLE tabela_braba TABLESPACE &#x5B;=] innodb_file_per_table;
</pre></div>


<p>Rename pode? pode!</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
ALTER TABLESPACE tablespace_braba RENAME TO tablespace_braba_01;
</pre></div>


<p class="has-red-color has-text-color has-link-color wp-elements-88ae3e7d99025178983d77c5bf3715e6">Brincadeira tem hora: Durante o rename de uma tablespace, todas as tabelas relacionadas a ela sofre lock de metadados 🚨.</p>



<p class="has-red-color has-text-color has-link-color wp-elements-bcfaedfd953d27d6e5c3cd5674542aaa">Também não é possivel realizar o RENAME enquanto as tabelas estiverem com: LOCK TABLES ou FLUSH TABLES WITH READ LOCK.</p>



<p>E por fim, dropar uma tablespace no MySQL:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
DROP TABLESPACE tablespace_braba;
</pre></div>


<h3 class="wp-block-heading"><strong>Vantagens dos General Tablespaces</strong></h3>



<ul class="wp-block-list">
<li><strong>Armazenamento Centralizado</strong>: Múltiplas tabelas podem compartilhar o mesmo arquivo, simplificando o gerenciamento.</li>



<li><strong>Compressão de Dados</strong>: Suporta tabelas com row format&nbsp;<code>COMPRESSED</code>, reduzindo o uso de espaço em disco.</li>



<li><strong>Eficiência</strong>: Ideal para cenários onde várias tabelas têm padrões de acesso semelhantes.</li>
</ul>



<h2 class="wp-block-heading">Combinações permitidas de tamanho de página para tabelas compactadas</h2>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>InnoDB Page Size</th><th>FILE_BLOCK_SIZE Value</th><th>KEY_BLOCK_SIZE Value</th></tr></thead><tbody><tr><th>64KB</th><td>64K (65536)</td><td>Compression is not supported</td></tr><tr><th>32KB</th><td>32K (32768)</td><td>Compression is not supported</td></tr><tr><th>16KB</th><td>16K (16384)</td><td>None. If&nbsp;<a href="https://dev.mysql.com/doc/refman/8.4/en/innodb-parameters.html#sysvar_innodb_page_size"><code>innodb_page_size</code></a>&nbsp;is equal to&nbsp;<code>FILE_BLOCK_SIZE</code>, the tablespace cannot contain a compressed table.</td></tr><tr><th>16KB</th><td>8K (8192)</td><td>8</td></tr><tr><th>16KB</th><td>4K (4096)</td><td>4</td></tr><tr><th>16KB</th><td>2K (2048)</td><td>2</td></tr><tr><th>16KB</th><td>1K (1024)</td><td>1</td></tr><tr><th>8KB</th><td>8K (8192)</td><td>None. If&nbsp;<a href="https://dev.mysql.com/doc/refman/8.4/en/innodb-parameters.html#sysvar_innodb_page_size"><code>innodb_page_size</code></a>&nbsp;is equal to&nbsp;<code>FILE_BLOCK_SIZE</code>, the tablespace cannot contain a compressed table.</td></tr><tr><th>8KB</th><td>4K (4096)</td><td>4</td></tr><tr><th>8KB</th><td>2K (2048)</td><td>2</td></tr><tr><th>8KB</th><td>1K (1024)</td><td>1</td></tr><tr><th>4KB</th><td>4K (4096)</td><td>None. If&nbsp;<a href="https://dev.mysql.com/doc/refman/8.4/en/innodb-parameters.html#sysvar_innodb_page_size"><code>innodb_page_size</code></a>&nbsp;is equal to&nbsp;<code>FILE_BLOCK_SIZE</code>, the tablespace cannot contain a compressed table.</td></tr><tr><th>4KB</th><td>2K (2048)</td><td>2</td></tr><tr><th>4KB</th><td>1K (1024)</td><td>1</td></tr></tbody></table><figcaption class="wp-element-caption"><strong>MySQL 8.4 Reference Manual &#8211; 17.6.3.3&nbsp;General Tablespaces</strong></figcaption></figure>



<h3 class="wp-block-heading"><strong>Quando usar Tablespaces no golfinho?</strong></h3>



<ul class="wp-block-list">
<li><strong>Cenários de Compressão</strong>: Se você precisa economizar espaço em disco, tablespaces com compressão são uma ótima opção.</li>



<li><strong>Armazenamento Centralizado</strong>: Para ambientes com múltiplas tabelas relacionadas, general tablespaces podem simplificar o gerenciamento.</li>



<li><strong>Controle de Localização</strong>: Se você precisa armazenar dados em um diretório específico (por exemplo, em um disco de alta performance [SSD, NVMe, Optane etc e tal]), tablespaces permitem esse controle.</li>
</ul>



<p class="has-medium-font-size"><strong>REFERENCE GUIDE:</strong></p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
-- ============================================================================
-- COMANDOS CREATE TABLESPACE MAIS COMPLETOS POR ENGINE
-- ============================================================================

-- ============================================================================
-- 1. InnoDB ENGINE - TABLESPACE REGULAR
-- ============================================================================
CREATE TABLESPACE ts_innodb_complete
ADD DATAFILE '/var/lib/mysql/ts_innodb_complete.ibd'
AUTOEXTEND_SIZE = 64M
FILE_BLOCK_SIZE = 16384
ENCRYPTION = 'Y'
ENGINE = InnoDB;

-- ============================================================================
-- 2. InnoDB ENGINE - UNDO TABLESPACE
-- ============================================================================
CREATE UNDO TABLESPACE undo_ts_innodb_complete
ADD DATAFILE '/var/lib/mysql/undo_ts_innodb_complete.ibu'
AUTOEXTEND_SIZE = 128M
FILE_BLOCK_SIZE = 16384
ENCRYPTION = 'N'
ENGINE = InnoDB;

-- ============================================================================
-- 3. NDB ENGINE - TABLESPACE COMPLETO
-- ============================================================================
-- Primeiro, criar o LOGFILE GROUP (prerequisito para NDB tablespace)
CREATE LOGFILE GROUP lg_ndb_complete
ADD UNDOFILE 'undo_lg_ndb_complete.dat'
INITIAL_SIZE = 128M
UNDO_BUFFER_SIZE = 64M
ENGINE = NDB;

-- Agora criar o TABLESPACE NDB
CREATE TABLESPACE ts_ndb_complete
ADD DATAFILE 'ts_ndb_complete.dat'
USE LOGFILE GROUP lg_ndb_complete
AUTOEXTEND_SIZE = 32M
EXTENT_SIZE = 1M
INITIAL_SIZE = 256M
MAX_SIZE = 2G
NODEGROUP = 0
WAIT
COMMENT = 'Tablespace NDB completo para cluster'
ENGINE = NDB;

-- ============================================================================
-- 4. NDB ENGINE - UNDO TABLESPACE
-- ============================================================================
CREATE UNDO TABLESPACE undo_ts_ndb_complete
ADD DATAFILE 'undo_ts_ndb_complete.dat'
USE LOGFILE GROUP lg_ndb_complete
AUTOEXTEND_SIZE = 16M
EXTENT_SIZE = 512K
INITIAL_SIZE = 128M
MAX_SIZE = 1G
NODEGROUP = 1
WAIT
COMMENT = 'Undo tablespace NDB para transações'
ENGINE = NDB;

-- ============================================================================
-- EXPLICAÇÃO DOS PARÂMETROS
-- ============================================================================

/*
PARÂMETROS COMUNS (InnoDB e NDB):
- ADD DATAFILE: Especifica o arquivo de dados
- AUTOEXTEND_SIZE: Tamanho do incremento automático
- ENGINE: Engine de armazenamento

PARÂMETROS EXCLUSIVOS InnoDB:
- FILE_BLOCK_SIZE: Tamanho do bloco (512, 1024, 2048, 4096, 8192, 16384, 32768, 65536)
- ENCRYPTION: Criptografia ('Y' ou 'N')

PARÂMETROS EXCLUSIVOS NDB:
- USE LOGFILE GROUP: Grupo de log files (obrigatório)
- EXTENT_SIZE: Tamanho da extensão (32K-2G)
- INITIAL_SIZE: Tamanho inicial
- MAX_SIZE: Tamanho máximo
- NODEGROUP: ID do grupo de nós
- WAIT: Aguarda conclusão da operação
- COMMENT: Comentário descritivo

VALORES RECOMENDADOS:
- FILE_BLOCK_SIZE InnoDB: 16384 (padrão)
- EXTENT_SIZE NDB: 1M (padrão)
- AUTOEXTEND_SIZE: 64M para InnoDB, 32M para NDB
*/

-- ============================================================================
-- MYSQL TABLESPACES COM MÚLTIPLOS DATAFILES
-- ============================================================================

/*
- InnoDB: NÃO suporta múltiplos datafiles no CREATE TABLESPACE
- NDB: SIM, suporta múltiplos datafiles nativamente
*/

-- ============================================================================
-- 1. InnoDB - LIMITAÇÃO: APENAS 1 DATAFILE NO CREATE
-- ============================================================================

-- ❌ ISTO NÃO FUNCIONA NO InnoDB:
-- CREATE TABLESPACE ts_innodb
-- ADD DATAFILE 'file1.ibd', 'file2.ibd', 'file3.ibd'  -- ERRO!
-- ENGINE = InnoDB;

-- ✅ InnoDB: Apenas 1 datafile no CREATE
CREATE TABLESPACE ts_innodb_inicial
ADD DATAFILE '/var/lib/mysql/ts_innodb_file1.ibd'
AUTOEXTEND_SIZE = 64M
FILE_BLOCK_SIZE = 16384
ENCRYPTION = 'Y'
ENGINE = InnoDB;

-- Para adicionar mais datafiles no InnoDB, você deve usar ALTER depois:
-- NOTA: ALTER TABLESPACE ADD DATAFILE não é suportado no InnoDB!
-- InnoDB usa auto-extend ao invés de múltiplos arquivos

-- ============================================================================
-- 2. NDB - SUPORTE COMPLETO A MÚLTIPLOS DATAFILES
-- ============================================================================

-- Primeiro criar o LOGFILE GROUP
CREATE LOGFILE GROUP lg_multiple
ADD UNDOFILE 'undo_multiple.dat'
INITIAL_SIZE = 128M
UNDO_BUFFER_SIZE = 64M
ENGINE = NDB;

-- ✅ NDB: Múltiplos datafiles são suportados via ALTER
CREATE TABLESPACE ts_ndb_multiple
ADD DATAFILE 'ndb_file1.dat'
USE LOGFILE GROUP lg_multiple
INITIAL_SIZE = 256M
EXTENT_SIZE = 1M
MAX_SIZE = 2G
ENGINE = NDB;

-- Adicionar mais datafiles ao tablespace NDB existente
ALTER TABLESPACE ts_ndb_multiple
ADD DATAFILE 'ndb_file2.dat'
INITIAL_SIZE = 256M
ENGINE = NDB;

ALTER TABLESPACE ts_ndb_multiple
ADD DATAFILE 'ndb_file3.dat'
INITIAL_SIZE = 256M
ENGINE = NDB;

ALTER TABLESPACE ts_ndb_multiple
ADD DATAFILE 'ndb_file4.dat'
INITIAL_SIZE = 256M
ENGINE = NDB;

-- ============================================================================
-- 3. VERIFICAR DATAFILES DE UM TABLESPACE
-- ============================================================================

-- Ver informações dos tablespaces e seus arquivos
SELECT 
    TABLESPACE_NAME,
    FILE_NAME,
    FILE_TYPE,
    TOTAL_EXTENTS,
    EXTENT_SIZE,
    INITIAL_SIZE,
    MAXIMUM_SIZE,
    ENGINE
FROM INFORMATION_SCHEMA.FILES 
WHERE TABLESPACE_NAME = 'ts_ndb_multiple'
ORDER BY FILE_NAME;

-- Para InnoDB, ver general tablespaces
SELECT 
    SPACE,
    NAME,
    FLAG,
    ROW_FORMAT,
    PAGE_SIZE,
    SPACE_TYPE
FROM INFORMATION_SCHEMA.INNODB_TABLESPACES
WHERE NAME = 'ts_innodb_inicial';

-- ============================================================================
-- 4. EXEMPLO PRÁTICO: DISTRIBUÇÃO DE CARGA EM NDB
-- ============================================================================

-- Cenário: Tablespace com 4 datafiles em diferentes discos
CREATE LOGFILE GROUP lg_distributed
ADD UNDOFILE '/disk1/mysql/undo_distributed.dat'
INITIAL_SIZE = 256M
UNDO_BUFFER_SIZE = 128M
ENGINE = NDB;

CREATE TABLESPACE ts_distributed
ADD DATAFILE '/disk2/mysql/data_file1.dat'
USE LOGFILE GROUP lg_distributed
INITIAL_SIZE = 1G
EXTENT_SIZE = 1M
MAX_SIZE = 10G
NODEGROUP = 0
ENGINE = NDB;

-- Adicionar datafiles em diferentes discos para performance
ALTER TABLESPACE ts_distributed
ADD DATAFILE '/disk3/mysql/data_file2.dat'
INITIAL_SIZE = 1G
ENGINE = NDB;

ALTER TABLESPACE ts_distributed
ADD DATAFILE '/disk4/mysql/data_file3.dat'
INITIAL_SIZE = 1G
ENGINE = NDB;

ALTER TABLESPACE ts_distributed
ADD DATAFILE '/disk5/mysql/data_file4.dat'
INITIAL_SIZE = 1G
ENGINE = NDB;

-- ============================================================================
-- 5. ALTERNATIVAS PARA InnoDB
-- ============================================================================

/*
Como InnoDB não suporta múltiplos datafiles por tablespace,
as alternativas são:

1. USAR AUTO-EXTEND (recomendado)
   - O arquivo cresce automaticamente conforme necessário
   - Mais simples de gerenciar

2. MÚLTIPLOS TABLESPACES
   - Criar vários tablespaces com 1 datafile cada
   - Distribuir tabelas entre eles

3. PARTICIONAMENTO
   - Particionar tabelas grandes
   - Cada partição pode estar em tablespace diferente
*/

-- Exemplo: Múltiplos tablespaces InnoDB
CREATE TABLESPACE ts_innodb_part1
ADD DATAFILE '/disk1/mysql/ts_part1.ibd'
AUTOEXTEND_SIZE = 64M
ENGINE = InnoDB;

CREATE TABLESPACE ts_innodb_part2
ADD DATAFILE '/disk2/mysql/ts_part2.ibd'
AUTOEXTEND_SIZE = 64M
ENGINE = InnoDB;

CREATE TABLESPACE ts_innodb_part3
ADD DATAFILE '/disk3/mysql/ts_part3.ibd'
AUTOEXTEND_SIZE = 64M
ENGINE = InnoDB;

-- Tabela particionada usando múltiplos tablespaces
CREATE TABLE vendas_particionada (
    id INT AUTO_INCREMENT,
    data_venda DATE,
    valor DECIMAL(10,2),
    PRIMARY KEY (id, data_venda)
)
PARTITION BY RANGE (YEAR(data_venda)) (
    PARTITION p2023 VALUES LESS THAN (2024) TABLESPACE ts_innodb_part1,
    PARTITION p2024 VALUES LESS THAN (2025) TABLESPACE ts_innodb_part2,
    PARTITION p2025 VALUES LESS THAN (2026) TABLESPACE ts_innodb_part3
);

-- ============================================================================
-- RESUMO FINAL
-- ============================================================================

/*
CAPACIDADES POR ENGINE:

InnoDB:
✗ Não suporta múltiplos datafiles no CREATE TABLESPACE
✗ Não suporta ALTER TABLESPACE ADD DATAFILE
✓ Suporta auto-extend (recomendado)
✓ Alternativa: múltiplos tablespaces + particionamento

NDB:
✓ Suporta múltiplos datafiles via ALTER TABLESPACE
✓ Ideal para distribuição de carga em cluster
✓ Permite adicionar datafiles dinamicamente
✓ Melhor controle sobre localização dos arquivos

RECOMENDAÇÃO:
- InnoDB: Use auto-extend ou particionamento
- NDB: Use múltiplos datafiles conforme necessário
*/

-- ============================================================================
-- COMANDOS ALTER TABLESPACE MAIS COMPLETOS POR ENGINE
-- ============================================================================

-- ============================================================================
-- 1. NDB ENGINE - OPERAÇÕES COM DATAFILES
-- ============================================================================

-- Adicionar datafile ao tablespace NDB
ALTER TABLESPACE ts_ndb_complete
ADD DATAFILE 'ts_ndb_additional_01.dat'
INITIAL_SIZE = 512M
WAIT
ENGINE = NDB;

-- Adicionar múltiplos datafiles sequencialmente
ALTER TABLESPACE ts_ndb_complete
ADD DATAFILE 'ts_ndb_additional_02.dat'
INITIAL_SIZE = 1G
WAIT
ENGINE = NDB;

ALTER TABLESPACE ts_ndb_complete
ADD DATAFILE 'ts_ndb_additional_03.dat'
INITIAL_SIZE = 1G
WAIT
ENGINE = NDB;

-- Remover datafile do tablespace NDB
ALTER TABLESPACE ts_ndb_complete
DROP DATAFILE 'ts_ndb_additional_01.dat'
WAIT
ENGINE = NDB;

-- Renomear tablespace NDB
ALTER TABLESPACE ts_ndb_complete
RENAME TO ts_ndb_renamed
ENGINE = NDB;

-- ============================================================================
-- 2. NDB ENGINE - UNDO TABLESPACE OPERATIONS
-- ============================================================================

-- Adicionar datafile ao UNDO tablespace NDB
ALTER UNDO TABLESPACE undo_ts_ndb_complete
ADD DATAFILE 'undo_ts_ndb_additional.dat'
INITIAL_SIZE = 256M
WAIT
ENGINE = NDB;

-- Remover datafile do UNDO tablespace NDB
ALTER UNDO TABLESPACE undo_ts_ndb_complete
DROP DATAFILE 'undo_ts_ndb_additional.dat'
WAIT
ENGINE = NDB;

-- Renomear UNDO tablespace NDB
ALTER UNDO TABLESPACE undo_ts_ndb_complete
RENAME TO undo_ts_ndb_renamed
ENGINE = NDB;

-- ============================================================================
-- 3. InnoDB ENGINE - ADICIONAR DATAFILES E CONFIGURAÇÕES
-- ============================================================================

-- ✅ FUNCIONA: Adicionar datafile ao tablespace InnoDB
-- (Suportado em versões específicas do MySQL/MariaDB)
ALTER TABLESPACE ts_innodb_complete
ADD DATAFILE '/u01/oradata/df_innodb_02.ibd'
INITIAL_SIZE = 48M
ENGINE = InnoDB;

-- Adicionar múltiplos datafiles ao InnoDB
ALTER TABLESPACE ts_innodb_complete
ADD DATAFILE '/u01/oradata/df_innodb_03.ibd'
INITIAL_SIZE = 64M
ENGINE = InnoDB;

ALTER TABLESPACE ts_innodb_complete
ADD DATAFILE '/u01/oradata/df_innodb_04.ibd'
INITIAL_SIZE = 128M
ENGINE = InnoDB;

-- Alterar AUTOEXTEND_SIZE do tablespace InnoDB
ALTER TABLESPACE ts_innodb_complete
AUTOEXTEND_SIZE = 128M
ENGINE = InnoDB;

-- Ativar criptografia no tablespace InnoDB
ALTER TABLESPACE ts_innodb_complete
ENCRYPTION = 'Y'
AUTOEXTEND_SIZE = 64M
ENGINE = InnoDB;

-- Desativar criptografia no tablespace InnoDB
ALTER TABLESPACE ts_innodb_complete
ENCRYPTION = 'N'
ENGINE = InnoDB;

-- Renomear tablespace InnoDB
ALTER TABLESPACE ts_innodb_complete
RENAME TO ts_innodb_renamed
AUTOEXTEND_SIZE = 64M
ENCRYPTION = 'Y'
ENGINE = InnoDB;

-- ============================================================================
-- 4. InnoDB ENGINE - UNDO TABLESPACE STATUS
-- ============================================================================

-- Definir UNDO tablespace como ATIVO
ALTER UNDO TABLESPACE undo_ts_innodb_complete
SET ACTIVE
AUTOEXTEND_SIZE = 256M
ENCRYPTION = 'Y'
ENGINE = InnoDB;

-- Definir UNDO tablespace como INATIVO
ALTER UNDO TABLESPACE undo_ts_innodb_complete
SET INACTIVE
AUTOEXTEND_SIZE = 128M
ENCRYPTION = 'N'
ENGINE = InnoDB;

-- Renomear UNDO tablespace InnoDB com todas as opções
ALTER UNDO TABLESPACE undo_ts_innodb_complete
RENAME TO undo_ts_innodb_renamed
SET ACTIVE
AUTOEXTEND_SIZE = 512M
ENCRYPTION = 'Y'
ENGINE = InnoDB;

-- ============================================================================
-- 5. OPERAÇÕES COMBINADAS COMPLEXAS
-- ============================================================================

-- NDB: Adicionar datafile com todas opções disponíveis
ALTER TABLESPACE ts_ndb_production
ADD DATAFILE '/data/mysql/ndb/ts_prod_extra_01.dat'
INITIAL_SIZE = 2G
WAIT
RENAME TO ts_ndb_production_v2
ENGINE = NDB;

-- InnoDB: Modificar todas configurações simultaneamente
ALTER TABLESPACE ts_innodb_production
RENAME TO ts_innodb_production_v2
AUTOEXTEND_SIZE = 256M
ENCRYPTION = 'Y'
ENGINE = InnoDB;

-- InnoDB UNDO: Configuração completa de produção
ALTER UNDO TABLESPACE undo_production
RENAME TO undo_production_primary
SET ACTIVE
AUTOEXTEND_SIZE = 1G
ENCRYPTION = 'Y'
ENGINE = InnoDB;

-- ============================================================================
-- 6. CENÁRIOS PRÁTICOS DE MANUTENÇÃO
-- ============================================================================

-- Cenário 1: Expansão de capacidade NDB
-- Adicionar múltiplos datafiles para aumentar capacidade
ALTER TABLESPACE ts_app_data
ADD DATAFILE '/storage/fast/mysql/app_data_ssd_01.dat'
INITIAL_SIZE = 5G
WAIT
ENGINE = NDB;

ALTER TABLESPACE ts_app_data
ADD DATAFILE '/storage/bulk/mysql/app_data_bulk_01.dat'
INITIAL_SIZE = 10G
WAIT
ENGINE = NDB;

-- Cenário 2: Migração e otimização InnoDB
-- Renomear e otimizar configurações
ALTER TABLESPACE ts_legacy_data
RENAME TO ts_optimized_data
AUTOEXTEND_SIZE = 512M
ENCRYPTION = 'Y'
ENGINE = InnoDB;

-- Cenário 3: Gerenciamento de UNDO tablespaces
-- Alternar entre UNDO tablespaces para manutenção
ALTER UNDO TABLESPACE undo_primary
SET INACTIVE
ENGINE = InnoDB;

ALTER UNDO TABLESPACE undo_secondary
SET ACTIVE
AUTOEXTEND_SIZE = 2G
ENCRYPTION = 'Y'
ENGINE = InnoDB;

-- Cenário 4: Rebalanceamento de storage NDB
-- Remover datafiles de storage lento
ALTER TABLESPACE ts_high_performance
DROP DATAFILE 'slow_storage_file.dat'
WAIT
ENGINE = NDB;

-- Adicionar datafiles em storage rápido
ALTER TABLESPACE ts_high_performance
ADD DATAFILE '/nvme/mysql/high_perf_01.dat'
INITIAL_SIZE = 8G
WAIT
ENGINE = NDB;

-- ============================================================================
-- 7. VERIFICAÇÃO E MONITORAMENTO
-- ============================================================================

-- Verificar status dos tablespaces após alterações
SELECT 
    TABLESPACE_NAME,
    FILE_NAME,
    FILE_TYPE,
    TOTAL_EXTENTS,
    FREE_EXTENTS,
    INITIAL_SIZE,
    MAXIMUM_SIZE,
    AUTOEXTEND_SIZE,
    ENGINE
FROM INFORMATION_SCHEMA.FILES 
WHERE ENGINE IN ('NDB', 'InnoDB')
ORDER BY TABLESPACE_NAME, FILE_NAME;

-- Verificar UNDO tablespaces InnoDB
SELECT 
    SPACE,
    NAME,
    STATE,
    SPACE_TYPE
FROM INFORMATION_SCHEMA.INNODB_TABLESPACES
WHERE SPACE_TYPE = 'Undo'
ORDER BY NAME;

-- ============================================================================
-- EXPLICAÇÃO DETALHADA DOS PARÂMETROS
-- ============================================================================

/*
PARÂMETROS POR ENGINE:

NDB EXCLUSIVO:
- ADD DATAFILE: Adiciona novo arquivo de dados
- DROP DATAFILE: Remove arquivo de dados (deve estar vazio)
- INITIAL_SIZE: Tamanho inicial do novo datafile
- WAIT: Aguarda conclusão da operação

InnoDB (DEPENDE DA VERSÃO):
- ADD DATAFILE: ✅ SUPORTADO em versões específicas
- INITIAL_SIZE: Tamanho inicial do novo datafile
- AUTOEXTEND_SIZE: Tamanho do incremento automático
- SET ACTIVE/INACTIVE: Estado do UNDO tablespace
- ENCRYPTION: Ativação/desativação da criptografia

PARÂMETROS COMUNS:
- RENAME TO: Renomeia o tablespace
- ENGINE: Especifica a engine (pode ser omitido)

SUPORTE POR VERSÃO:

MySQL 8.0 (documentação oficial):
❌ ADD DATAFILE não suportado para InnoDB

Versões específicas/MariaDB:
✅ ADD DATAFILE suportado para InnoDB
✅ INITIAL_SIZE funciona com InnoDB

IMPORTANTE: 
- O suporte pode variar entre versões do MySQL/MariaDB
- Sempre teste em ambiente de desenvolvimento primeiro
- Verifique a documentação da sua versão específica

VALORES RECOMENDADOS:
- AUTOEXTEND_SIZE InnoDB: 64M-1G (dependendo do uso)
- INITIAL_SIZE: 48M-1G (dependendo do datafile)
- ENCRYPTION: 'Y' para dados sensíveis
- Sempre usar WAIT em operações NDB críticas
*/
</pre></div>


<p>Bueno, é isso ae cambada, mais uma do golfinho pra vocês, espero que aproveitem e se organizem como bons DBA Oracle, quero dizer, DBA MySQL👀</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>MySQL InnoDB Cluster &#8211; Descomplicado</title>
		<link>https://furushima.com.br/blog/mysql-innodb-cluster-descomplicado/</link>
		
		<dc:creator><![CDATA[Acacio Lima Rocha]]></dc:creator>
		<pubDate>Sat, 27 Sep 2025 16:37:12 +0000</pubDate>
				<category><![CDATA[MySQL]]></category>
		<guid isPermaLink="false">https://furushima.com.br/?p=2896</guid>

					<description><![CDATA[Iaeeeeeee cambada, tudo na paz? bora falar mais um cadim do database do golfinho? ⚠️ CONTÉM TEXTO MELHORADO POR AI &#8211; E TA TUDO BEM (SE SOUBER USAR 🤭)⚠️ Neste artigo aqui eu vou falar do setup do InnoDB Cluster (mostrar como faz também) e vou dar alguns detalhes de como administrar, monitorar etc, nada [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Iaeeeeeee cambada, tudo na paz? bora falar mais um cadim do database do golfinho?</p>



<p class="has-vivid-red-color has-text-color has-link-color wp-elements-6d5b5a8f143d711856e2bac48efce38c"><strong>⚠️ CONTÉM TEXTO MELHORADO POR AI  &#8211; E TA TUDO BEM (SE SOUBER USAR 🤭)⚠️ </strong></p>



<p>Neste artigo aqui eu vou falar do setup do InnoDB Cluster (mostrar como faz também) e vou dar alguns detalhes de como administrar, monitorar etc, nada de outro mundo. E não, não é parecido com o Oracle RAC mas é muito legal quanto.</p>



<h3 class="wp-block-heading">O que é o MySQL InnoDB Cluster?</h3>



<p>O InnoDB Cluster é uma arquitetura de alta disponibilidade nativa do MySQL que combina replicação automagica, failover integrado e escalabilidade da parada toda. Ele utiliza de Group Replication para sincronizar instâncias de banco de dados, garantindo consistência entre os nós e permitindo a distribuição de cargas de trabalho. De novo, não existem nada como o Oracle RAC mesmo 😆 (e ponto final).</p>



<h2 class="wp-block-heading">Bora para a <a href="https://dev.mysql.com/doc/refman/8.4/en/mysql-innodb-cluster-introduction.html" target="_blank" rel="noreferrer noopener">arquitetura</a>:</h2>



<p>A arquitetura de um cluster de alta disponibilidade (High Availability Cluster) do MySQL com Group Replication:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img alt="" decoding="async" src="https://acaciolrdba.wordpress.com/wp-content/uploads/2024/12/image.png?w=394" alt="" class="wp-image-1063" style="width:534px;height:auto"/><figcaption class="wp-element-caption">Imagem tirada da doc oficial</figcaption></figure></div>


<h3 class="wp-block-heading">Componentes:</h3>



<ol class="wp-block-list">
<li><strong>Client App</strong>:
<ul class="wp-block-list">
<li>Representa as aplicações dos usuários que se conectam ao banco de dados.</li>



<li>Utiliza o <strong>MySQL Connector</strong> para comunicação com o cluster via MySQL Router.</li>
</ul>
</li>



<li><strong>MySQL Router</strong>:
<ul class="wp-block-list">
<li>Um middleware que atua como intermediário entre os aplicativos e os servidores MySQL.</li>



<li>Direciona as solicitações de leitura/escrita para o nó primário (Primary Instance R/W) e distribui as leituras entre os nós secundários (Secondary Instances R/O), dependendo da configuração.</li>
</ul>
</li>



<li><strong>MySQL Shell (Cluster Admin)</strong>:
<ul class="wp-block-list">
<li>Uma interface de administração utilizada para gerenciar o cluster.</li>



<li>Faz uso da <strong>MySQL Admin API</strong> para configurar e monitorar o cluster, incluindo a inicialização do Group Replication.</li>
</ul>
</li>



<li><strong>MySQL Servers</strong>:
<ul class="wp-block-list">
<li><strong>Primary Instance R/W</strong>:
<ul class="wp-block-list">
<li>É o nó principal que processa as operações de leitura e escrita.</li>



<li>Participa do <strong>Group Replication</strong>, garantindo que as alterações sejam propagadas para os nós secundários.</li>
</ul>
</li>



<li><strong>Secondary Instances R/O</strong>:
<ul class="wp-block-list">
<li>São nós secundários configurados para replicação em tempo real.</li>



<li>São usados principalmente para operações de leitura, otimizando o desempenho do cluster.</li>
</ul>
</li>
</ul>
</li>
</ol>



<h3 class="wp-block-heading">Funcionamento:</h3>



<ul class="wp-block-list">
<li><strong>Group Replication</strong>:
<ul class="wp-block-list">
<li>Um protocolo de replicação nativa do MySQL usado para sincronizar os dados entre o nó primário e os nós secundários.</li>



<li>Assegura que todas as instâncias estejam atualizadas com as alterações feitas no nó primário.</li>
</ul>
</li>



<li><strong>Alta Disponibilidade</strong>:
<ul class="wp-block-list">
<li>Se o nó primário falhar, um dos nós secundários pode ser promovido automaticamente a nó primário para garantir a continuidade do serviço.</li>



<li>O <strong>MySQL Router</strong> ajusta automaticamente os encaminhamentos para refletir essa mudança.</li>
</ul>
</li>
</ul>



<h2 class="wp-block-heading">Setup do InnoDB Cluster</h2>



<p>Agora, vou mostrar o passo a passo para realizar o setup do cluster.</p>



<p>Topicos do role:</p>



<ul class="wp-block-list">
<li>Topologia</li>



<li>Pre-Requisitos</li>



<li>Instalação do MySQL e seus componentes (MySQL Shell e escambal) </li>



<li>Configuração do my.cnf</li>



<li>Setup do Cluster via MySQL Shell</li>



<li>Setup do MySQL Router</li>



<li>Teste de disponibilidade</li>
</ul>



<h2 class="wp-block-heading">Topologia da parada</h2>



<ul class="wp-block-list">
<li>myorcl1
<ul class="wp-block-list">
<li>192.168.10.101</li>
</ul>
</li>



<li>myorcl2
<ul class="wp-block-list">
<li>192.168.10.102</li>
</ul>
</li>



<li>myorcl3
<ul class="wp-block-list">
<li>192.168.10.103</li>
</ul>
</li>



<li>myrouter
<ul class="wp-block-list">
<li>192.168.10.100</li>
</ul>
</li>
</ul>



<h2 class="wp-block-heading">Pre-Requisitos (Do meu ambiente kkk)</h2>



<ul class="wp-block-list">
<li>Ubuntu 20
<ul class="wp-block-list">
<li>RAM 8GB</li>



<li>HD 40GB</li>
</ul>
</li>



<li>MySQL Server 8</li>



<li>MySQL Shell 8</li>



<li>MySQL Router 8</li>



<li>&#8220;DNS&#8221;
<ul class="wp-block-list">
<li>Config do /etc/hosts</li>
</ul>
</li>
</ul>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
127.0.0.1       localhost

# Configuração dos nós do cluster
192.168.61.101  myorcl1
192.168.61.102  myorcl2
192.168.61.103  myorcl3

# Configuração do MySQL Router
192.168.61.100  myrouter
</pre></div>


<h2 class="wp-block-heading">Instalação do MySQL e seus componentes (MySQL Shell e escambal) </h2>



<h3 class="wp-block-heading">Passo 1: Instalação do MySQL e MySQL Shell no Ubuntu</h3>



<h4 class="wp-block-heading">Instalar o MySQL Server</h4>



<p>Execute os comandos abaixo em <strong>cada servidor do cluster</strong> (<code>myorcl1</code>, <code>myorcl2</code>, <code>myorcl3</code>):</p>



<h5 class="wp-block-heading">Atualize os pacotes do sistema</h5>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
sudo apt update &amp;&amp; sudo apt upgrade -y
</pre></div>


<h5 class="wp-block-heading">Adicione o repositório do MySQL</h5>



<p>Baixe e adicione o repositório oficial do MySQL:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
wget https://dev.mysql.com/get/mysql-apt-config_0.8.26-1_all.deb
sudo dpkg -i mysql-apt-config_0.8.26-1_all.deb
sudo apt update
</pre></div>


<h5 class="wp-block-heading">Instale o MySQL Server</h5>



<p>Instale a versão desejada do MySQL Server (por exemplo, 8.0):</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
sudo apt install -y mysql-server
</pre></div>


<h5 class="wp-block-heading">Verifique se o serviço está ativo</h5>



<p>Inicie e habilite o MySQL para iniciar no boot:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
sudo systemctl start mysql

sudo systemctl enable mysql

Synchronizing state of mysql.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable mysql

sudo systemctl status mysql

● mysql.service - MySQL Community Server
   Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2024-12-29 10:15:32 UTC; 5min ago
 Main PID: 12345 (mysqld)
    Tasks: 37 (limit: 4915)
   Memory: 148.4M
   CGroup: /system.slice/mysql.service
           └─12345 /usr/sbin/mysqld

Dec 29 10:15:32 ubuntu-server systemd&#x5B;1]: Started MySQL Community Server.
</pre></div>


<h5 class="wp-block-heading">Realize a configuração inicial do MySQL</h5>



<p>Utilize o utilitário de configuração inicial do MySQL para definir senha e outras configs, so seguir o que tem na tela e ser feliz:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
sudo mysql_secure_installation
</pre></div>


<h4 class="wp-block-heading">Instalar o MySQL Shell</h4>



<h5 class="wp-block-heading">Instale o MySQL Shell</h5>



<p>O MySQL Shell pode ser instalado com o seguinte comando:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
sudo apt install -y mysql-shell
</pre></div>


<h5 class="wp-block-heading">Verifique a instalação do MySQL Shell</h5>



<p>Confirme que o MySQL Shell está instalado:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
mysqlsh --version
</pre></div>


<h5 class="wp-block-heading">Configurar o MySQL para aceitar conexões externas</h5>



<p>Pelo root:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
UPDATE mysql.user SET host = '%' WHERE user = 'root' AND host = '127.0.0.1';
FLUSH PRIVILEGES;
</pre></div>


<p>Pelo bind-adress:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
bind-address = 0.0.0.0
</pre></div>


<h3 class="wp-block-heading"><strong>Portas do firewall utilizadas no MySQL InnoDB Cluster</strong></h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Porta</th><th>Protocolo</th><th>Finalidade</th></tr></thead><tbody><tr><td>3306</td><td>TCP</td><td>Conexões ao banco de dados MySQL.</td></tr><tr><td>33061</td><td>TCP</td><td>Comunicação interna do Group Replication.</td></tr><tr><td>6446</td><td>TCP</td><td>MySQL Router (opcional, ajuste conforme necessário).</td></tr><tr><td>22</td><td>TCP</td><td>SSH (opcional, para administração remota).</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">Configuração do my.cnf</h2>



<p>vi no menimo: /etc/my.cnf</p>



<h5 class="wp-block-heading">MYorcl1</h5>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
&#x5B;mysqld]
server-id=1
log_bin=mysql-bin
binlog_checksum=NONE
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name=&quot;aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa&quot;
loose-group_replication_start_on_boot=OFF
loose-group_replication_local_address=&quot;192.168.10.101:33061&quot;
loose-group_replication_group_seeds=&quot;192.168.10.101:33061,192.168.10.102:33061,192.168.10.103:33061&quot;
loose-group_replication_bootstrap_group=OFF
bind-address=192.168.10.101
report_host=192.168.610.101
port=3306
</pre></div>


<h5 class="wp-block-heading">myorcl2</h5>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
&#x5B;mysqld]
server-id=2
log_bin=mysql-bin
binlog_checksum=NONE
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name=&quot;aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa&quot;
loose-group_replication_start_on_boot=OFF
loose-group_replication_local_address=&quot;192.168.10.102:33061&quot;
loose-group_replication_group_seeds=&quot;192.168.10.101:33061,192.168.10.102:33061,192.168.10.103:33061&quot;
loose-group_replication_bootstrap_group=OFF
bind-address=192.168.10.102
report_host=192.168.610.102
port=3307
</pre></div>


<h5 class="wp-block-heading">myorcl3</h5>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
&#x5B;mysqld]
server-id=3
log_bin=mysql-bin
binlog_checksum=NONE
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name=&quot;aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa&quot;
loose-group_replication_start_on_boot=OFF
loose-group_replication_local_address=&quot;192.168.10.103:33061&quot;
loose-group_replication_group_seeds=&quot;192.168.10.101:33061,192.168.10.102:33061,192.168.10.103:33061&quot;
loose-group_replication_bootstrap_group=OFF
bind-address=192.168.10.103
report_host=192.168.610.103
port=3308
</pre></div>


<h5 class="wp-block-heading">myrouter</h5>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
&#x5B;mysqld]
server-id=4
bind-address=192.168.10.100
report_host=192.168.10.100
port=6446
</pre></div>


<h2 class="wp-block-heading">Setup do Cluster via MySQL Shell</h2>



<p>Exemplos de como logar no MySQL Shell:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
mysqlsh --user=root --password --host=192.168.10.101 --port=3306 --js
mysqlsh --user=root --password --host=192.168.10.102 --port=3307 --js
mysqlsh --user=root --password --host=192.168.10.103 --port=3308 --js
</pre></div>


<p>No node myorcl1, vamos configurar a instancia:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
mysql-js &gt; dba.configureInstance();

Creating configuration for instance 'myorcl1'
Instance 'myorcl1' configured successfully.
</pre></div>


<p>Ainda no myorcl1, criamos o cluster:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
mysql-js &gt; var cluster = dba.createCluster(&quot;ClusterBrabo&quot;);

Creating cluster 'ClusterBrabo'...
Cluster 'ClusterBrabo' created successfully.
The cluster will be available once it is fully initialized.
Initializing cluster 'ClusterBrabo'...
Configuring instance 'myorcl1' for inclusion in the cluster...
Cluster 'ClusterBrabo' initialized and instance 'myorcl1' added successfully.
</pre></div>


<p>myorcl1 ainda, adicione os nodes myorcl2 e myorcl3 ao nosso cluster:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
mysql-js &gt; cluster.addInstance('root@192.168.10.102:3307');

Adding instance 'root@192.168.10.102' to cluster 'ClusterBrabo'...
Verifying the instance is running and accessible...
Verifying MySQL Group Replication status...
Configuring instance 'root@192.168.10.102' for Group Replication...
Adding instance 'root@192.168.10.102' to the cluster...
Instance 'root@192.168.10.102' added successfully to cluster 'ClusterBrabo'.

mysql-js &gt; cluster.addInstance('root@192.168.10.103:3308');

Adding instance 'root@192.168.10.103' to cluster 'ClusterBrabo'...
Verifying the instance is running and accessible...
Verifying MySQL Group Replication status...
Configuring instance 'root@192.168.10.103' for Group Replication...
Adding instance 'root@192.168.10.103' to the cluster...
Instance 'root@192.168.10.103' added successfully to cluster 'ClusterBrabo'.

</pre></div>


<p>Vamos dar um check na bagaça:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
mysql-js &gt; cluster.status()
{
  &quot;clusterName&quot;: &quot;ClusterBrabo&quot;,
  &quot;defaultReplicaSet&quot;: {
    &quot;name&quot;: &quot;default&quot;,
    &quot;primary&quot;: &quot;myorcl1:3306&quot;,
    &quot;ssl&quot;: &quot;REQUIRED&quot;,
    &quot;status&quot;: &quot;OK&quot;,
    &quot;statusText&quot;: &quot;Cluster is ONLINE and can tolerate up to ONE failure.&quot;,
    &quot;topology&quot;: {
      &quot;myorcl1:3306&quot;: {
        &quot;address&quot;: &quot;myorcl1:3306&quot;,
        &quot;memberRole&quot;: &quot;PRIMARY&quot;,
        &quot;mode&quot;: &quot;R/W&quot;,
        &quot;readReplicas&quot;: {},
        &quot;replicationLag&quot;: null,
        &quot;role&quot;: &quot;HA&quot;,
        &quot;status&quot;: &quot;ONLINE&quot;,
        &quot;version&quot;: &quot;8.0.23&quot;
      },
      &quot;myorcl2:3307&quot;: {
        &quot;address&quot;: &quot;myorcl2:3306&quot;,
        &quot;memberRole&quot;: &quot;SECONDARY&quot;,
        &quot;mode&quot;: &quot;R/O&quot;,
        &quot;readReplicas&quot;: {},
        &quot;replicationLag&quot;: null,
        &quot;role&quot;: &quot;HA&quot;,
        &quot;status&quot;: &quot;ONLINE&quot;,
        &quot;version&quot;: &quot;8.0.23&quot;
      },
      &quot;myorcl3:3308&quot;: {
        &quot;address&quot;: &quot;myorcl3:3306&quot;,
        &quot;memberRole&quot;: &quot;SECONDARY&quot;,
        &quot;mode&quot;: &quot;R/O&quot;,
        &quot;readReplicas&quot;: {},
        &quot;replicationLag&quot;: null,
        &quot;role&quot;: &quot;HA&quot;,
        &quot;status&quot;: &quot;ONLINE&quot;,
        &quot;version&quot;: &quot;8.0.23&quot;
      }
    },
    &quot;topologyMode&quot;: &quot;Single-Primary&quot;
  },
  &quot;groupInformationSourceMember&quot;: &quot;myorcl1:3306&quot;
}
</pre></div>


<h2 class="wp-block-heading">Setup do MySQL Router</h2>



<p>O <strong>MySQL Router</strong> é uma ferramenta que atua como um intermediário entre os clientes (aplicações ou usuários) e o <strong>InnoDB Cluster</strong>. Ele facilita o roteamento de conexões para os nós corretos do cluster, dependendo do tipo de operação que você deseja realizar.</p>



<h5 class="wp-block-heading">no myrouter:</h5>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
wget https://dev.mysql.com/get/Downloads/Router/mysql-router_8.0.40-1_amd64.deb

sudo dpkg -i mysql-router_8.0.40-1_amd64.deb

sudo apt-get install -f
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
mysqlrouter --bootstrap root@192.168.10.100:3306 --directory /path/to/mysqlrouter/data
</pre></div>


<p>Agora, vamos configurar o MySQL Router:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
sudo vi /etc/mysqlrouter/mysqlrouter.conf
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
&#x5B;logger]
level = INFO
file = /var/log/mysqlrouter.log

&#x5B;mysql-router]
user = mysql
socket = /var/lib/mysql/mysql.sock
connect_timeout = 10000
client_address = 0.0.0.0
client_port = 6446

&#x5B;health]
enabled = true
check_interval = 10
</pre></div>


<h5 class="wp-block-heading">onde:</h5>



<ul class="wp-block-list">
<li><strong>client_address</strong>: Define o IP ou hostname no qual o MySQL Router vai escutar.</li>



<li><strong>client_port</strong>: A porta na qual o Router vai escutar (ex.: 6446).</li>



<li><strong>connect_timeout</strong>: O tempo limite de conexão.</li>



<li><strong>read_timeout</strong>: O tempo limite de leitura.</li>
</ul>



<p>Se liga nos exemplos de como conectar usando o router:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
# Conexão de Leitura e Escrita (R/W)
# O MySQL Router redirecionará a conexão para o nó PRIMARY.
mysql -u root -p -h 192.168.61.100 -P 3306

# Conexão Somente Leitura (R/O)
# O MySQL Router redirecionará a conexão para um dos nós SECONDARY.
mysql -u root -p -h 192.168.61.100 -P 3307

# Verifica o nó ao qual você está conectado
SELECT @@hostname, @@port, @@server_id, @@read_only;
</pre></div>


<h2 class="wp-block-heading">Teste de disponibilidade</h2>



<p>Vamos agora parar o myorcl1 e ver o que acontece:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
sudo systemctl stop mysql
</pre></div>


<p>Vamos dar um check agora:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
mysql-js &gt; cluster.status()
{
  &quot;clusterName&quot;: &quot;ClusterBrabo&quot;,
  &quot;defaultReplicaSet&quot;: {
    &quot;name&quot;: &quot;default&quot;,
    &quot;primary&quot;: &quot;myorcl2:3306&quot;,
    &quot;ssl&quot;: &quot;REQUIRED&quot;,
    &quot;status&quot;: &quot;OK&quot;,
    &quot;statusText&quot;: &quot;Cluster is ONLINE but cannot tolerate further failures.&quot;,
    &quot;topology&quot;: {
      &quot;myorcl1:3306&quot;: {
        &quot;address&quot;: &quot;myorcl1:3306&quot;,
        &quot;memberRole&quot;: &quot;UNREACHABLE&quot;,
        &quot;mode&quot;: &quot;R/W&quot;,
        &quot;readReplicas&quot;: {},
        &quot;replicationLag&quot;: null,
        &quot;role&quot;: &quot;HA&quot;,
        &quot;status&quot;: &quot;OFFLINE&quot;,
        &quot;version&quot;: &quot;8.0.23&quot;
      },
      &quot;myorcl2:3307&quot;: {
        &quot;address&quot;: &quot;myorcl2:3306&quot;,
        &quot;memberRole&quot;: &quot;PRIMARY&quot;,
        &quot;mode&quot;: &quot;R/W&quot;,
        &quot;readReplicas&quot;: {},
        &quot;replicationLag&quot;: null,
        &quot;role&quot;: &quot;HA&quot;,
        &quot;status&quot;: &quot;ONLINE&quot;,
        &quot;version&quot;: &quot;8.0.23&quot;
      },
      &quot;myorcl3:3308&quot;: {
        &quot;address&quot;: &quot;myorcl3:3306&quot;,
        &quot;memberRole&quot;: &quot;SECONDARY&quot;,
        &quot;mode&quot;: &quot;R/O&quot;,
        &quot;readReplicas&quot;: {},
        &quot;replicationLag&quot;: null,
        &quot;role&quot;: &quot;HA&quot;,
        &quot;status&quot;: &quot;ONLINE&quot;,
        &quot;version&quot;: &quot;8.0.23&quot;
      }
    },
    &quot;topologyMode&quot;: &quot;Single-Primary&quot;
  },
  &quot;groupInformationSourceMember&quot;: &quot;myorcl2:3306&quot;
}
</pre></div>


<p>Legal, agora damos um start novamente:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
sudo systemctl start mysql
</pre></div>


<p>Damos então um rejoin (assim que vi por ai kkkkk):</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
mysql-js &gt; cluster.rejoinInstance('root@myorcl1:3306')
</pre></div>


<p>eeeeeee&#8230; ta ai:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
mysql-js &gt; cluster.status()
{
  &quot;clusterName&quot;: &quot;ClusterBrabo&quot;,
  &quot;defaultReplicaSet&quot;: {
    &quot;name&quot;: &quot;default&quot;,
    &quot;primary&quot;: &quot;myorcl2:3306&quot;,
    &quot;ssl&quot;: &quot;REQUIRED&quot;,
    &quot;status&quot;: &quot;OK&quot;,
    &quot;statusText&quot;: &quot;Cluster is ONLINE and can tolerate up to ONE failure.&quot;,
    &quot;topology&quot;: {
      &quot;myorcl1:3306&quot;: {
        &quot;address&quot;: &quot;myorcl1:3306&quot;,
        &quot;memberRole&quot;: &quot;SECONDARY&quot;,
        &quot;mode&quot;: &quot;R/O&quot;,
        &quot;readReplicas&quot;: {},
        &quot;replicationLag&quot;: null,
        &quot;role&quot;: &quot;HA&quot;,
        &quot;status&quot;: &quot;ONLINE&quot;,
        &quot;version&quot;: &quot;8.0.23&quot;
      },
      &quot;myorcl2:3307&quot;: {
        &quot;address&quot;: &quot;myorcl2:3306&quot;,
        &quot;memberRole&quot;: &quot;PRIMARY&quot;,
        &quot;mode&quot;: &quot;R/W&quot;,
        &quot;readReplicas&quot;: {},
        &quot;replicationLag&quot;: null,
        &quot;role&quot;: &quot;HA&quot;,
        &quot;status&quot;: &quot;ONLINE&quot;,
        &quot;version&quot;: &quot;8.0.23&quot;
      },
      &quot;myorcl3:3308&quot;: {
        &quot;address&quot;: &quot;myorcl3:3306&quot;,
        &quot;memberRole&quot;: &quot;SECONDARY&quot;,
        &quot;mode&quot;: &quot;R/O&quot;,
        &quot;readReplicas&quot;: {},
        &quot;replicationLag&quot;: null,
        &quot;role&quot;: &quot;HA&quot;,
        &quot;status&quot;: &quot;ONLINE&quot;,
        &quot;version&quot;: &quot;8.0.23&quot;
      }
    },
    &quot;topologyMode&quot;: &quot;Single-Primary&quot;
  },
  &quot;groupInformationSourceMember&quot;: &quot;myorcl2:3306&quot;
}
</pre></div>


<p>Ain, mas como sei quantas falhas meu cluster tolera? poxa, tem na literarua ramelão, se liga:</p>



<p>Existe uma formula para determinar quantas falhas o seu cluster pode tolerar, onde: S = Server, f = numero de falhas +1, então:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
S = 2f + 1
</pre></div>


<p>Por exemplo (tirado da literatura, de novo)</p>



<p>Se você tem um cluster com 7 nodes, a tolerancia a falhas é de até 3 🙃</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
7 = 2f + 1
6 = 2f
2f = 6
f = 6 / 2
f = 3
</pre></div>


<p>Agora algo mais proximo do nosso mundo (de pobre kkk), 3 servers:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
F = (3 – 1)/2
F = 2 / 2
F = 1
</pre></div>


<p>Então é isso, existe também a possobilidade de antes de você se matar em laboratorios ou ir pra produção com duvidas, você pode utilizar o <a href="https://dev.mysql.com/doc/mysql-shell/8.0/en/deploy-sandbox-instances.html" target="_blank" rel="noreferrer noopener">MySQL InnoDB Cluster SandBox</a> que é bem legal de brincar e entender um pouco do InnoDB Cluster.</p>



<p>Te um script doido que rola para criar um sandbox facil facil:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: python; title: ; notranslate">
# Introducing InnoDB Cluster
#
# This Python script is designed to set up an InnoDB Cluster in a sandbox.
#
# Note: Change the sandbox directory to match your preferred directory setup.
#
# The steps include:
# 1) Create the sandbox directory
# 2) Deploy instances
# 3) Create the cluster
# 4) Add instances to the cluster
# 5) Show the cluster status
#
# Updated for modern MySQL Shell versions
# Dr. Charles Bell, 2024 (Updated by Assistant)

import os
import time
from mysqlsh import dba, shell  # Import MySQL Shell modules

# Method to deploy a sandbox instance
def deploy_instance(port):
    try:
        dba.deploy_sandbox_instance(
            port,
            {
                'sandboxDir': '/home/user/idc_sandbox',  # Adjusted for Linux/macOS
                'password': 'root'
            }
        )
        print(f&quot;Instance deployed on port {port}&quot;)
    except Exception as e:
        print(f&quot;ERROR: Cannot set up the instance in the sandbox on port {port}. Error: {e}&quot;)
    time.sleep(1)

# Method to add an instance to the cluster
def add_instance(cluster, port):
    try:
        cluster.add_instance(
            f'root@localhost:{port}',
            {
                'password': 'root',
                'recoveryMethod': 'clone'  # Use 'clone' for modern MySQL versions
            }
        )
        print(f&quot;Instance on port {port} added to the cluster.&quot;)
    except Exception as e:
        print(f&quot;ERROR: Cannot add instance on port {port} to the cluster. Error: {e}&quot;)
    time.sleep(1)

# Main script
if __name__ == &quot;__main__&quot;:
    print(&quot;##### STEP 1 of 5 : CREATE SANDBOX DIRECTORY #####&quot;)
    sandbox_dir = '/home/user/idc_sandbox'  # Adjusted for Linux/macOS
    if not os.path.exists(sandbox_dir):
        os.mkdir(sandbox_dir)
        print(f&quot;Sandbox directory created at {sandbox_dir}&quot;)
    else:
        print(f&quot;Sandbox directory already exists at {sandbox_dir}&quot;)

    print(&quot;##### STEP 2 of 5 : DEPLOY INSTANCES #####&quot;)
    deploy_instance(3311)
    deploy_instance(3312)
    deploy_instance(3313)
    deploy_instance(3314)

    print(&quot;##### STEP 3 of 5 : CREATE CLUSTER #####&quot;)
    try:
        shell.connect('root@localhost:3311', {'password': 'root'})
        my_cluster = dba.create_cluster(
            'MyCluster',
            {
                'multiPrimary': False  # Updated parameter name for single-primary mode
            }
        )
        print(&quot;Cluster 'MyCluster' created successfully.&quot;)
    except Exception as e:
        print(f&quot;ERROR: Cannot create the cluster. Error: {e}&quot;)
    time.sleep(1)

    print(&quot;##### STEP 4 of 5 : ADD INSTANCES TO CLUSTER #####&quot;)
    add_instance(my_cluster, 3312)
    add_instance(my_cluster, 3313)
    add_instance(my_cluster, 3314)

    print(&quot;##### STEP 5 of 5 : SHOW CLUSTER STATUS #####&quot;)
    try:
        shell.connect('root@localhost:3311', {'password': 'root'})
        my_cluster = dba.get_cluster('MyCluster')
        status = my_cluster.status()
        print(&quot;Cluster Status:&quot;)
        print(status)
    except Exception as e:
        print(f&quot;ERROR: Cannot retrieve cluster status. Error: {e}&quot;)
</pre></div>


<p>Ah, tinha esquecido dos comandinhos para administrar e monitorar o cluster:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
// Verificar o status do cluster
cluster.status()

// Verificar o status detalhado de cada nó
cluster.status({extended: true})

// Adicionar um novo nó ao cluster
// Substitua 'senha' pela senha correta do usuário root
cluster.addInstance('root@myorcl4:3306', {password: 'senha'})

// Remover um nó do cluster
// Exemplo: Remover o nó myorcl3:3306
cluster.removeInstance('root@myorcl3:3306', {password: 'senha'})

// Promover um nó secundário a primário (failover manual)
// Exemplo: Promover o nó myorcl3:3306 a primário
cluster.setPrimaryInstance('myorcl3:3306')

// Alterar o modo de topologia para Multi-Primary
cluster.switchToMultiPrimaryMode()

// Alterar o modo de topologia para Single-Primary
cluster.switchToSinglePrimaryMode()

// Reconfigurar o cluster para reintegrar um nó
// Exemplo: Reintegrar o nó myorcl3:3306 ao cluster
cluster.rejoinInstance('myorcl3:3306')

// Remover o cluster completamente
// Nome do cluster: ClusterBrabo
dba.dropCluster('ClusterBrabo')

// Fazer backup de uma instância
// Exemplo: Fazer backup do nó primário myorcl2:3306
util.dumpInstance('root@myorcl2:3306', {password: 'senha', outputUrl: 'file:///backups/cluster_backup'})

// Verificar a configuração do cluster
cluster.describe()

// Atualizar a versão do cluster após atualizar o MySQL
cluster.upgradeMetadata()

// Listar todos os clusters disponíveis no ambiente
dba.getClusters()

// Verificar os nós disponíveis para serem adicionados ao cluster
// Isso ajuda a identificar instâncias MySQL que podem ser configuradas como parte do cluster
dba.checkInstanceConfiguration('root@myorcl4:3306', {password: 'senha'})

// Configurar uma instância MySQL para ser usada no cluster
// Use este comando antes de adicionar uma instância ao cluster
dba.configureInstance('root@myorcl4:3306', {password: 'senha'})

// Verificar a configuração de uma instância específica
// Isso ajuda a diagnosticar problemas de configuração em um nó
dba.checkInstanceConfiguration('root@myorcl3:3306', {password: 'senha'})

// Verificar a replicação entre os nós do cluster
// Isso exibe informações sobre o atraso de replicação e o status de cada nó
cluster.checkInstanceState('myorcl3:3306')

// Alterar o modo de recuperação automática de um nó
// Exemplo: Configurar o nó myorcl3:3306 para tentar se reconectar automaticamente ao cluster
cluster.setInstanceOption('myorcl3:3306', 'autoRejoinTries', 3)

// Alterar o tempo limite de espera para operações de cluster
// Exemplo: Configurar o tempo limite para 60 segundos
cluster.setOption('operationTimeout', 60)

// Verificar as opções configuradas no cluster
cluster.options()

// Verificar as opções configuradas para um nó específico
cluster.getInstanceOptions('myorcl3:3306')

// Forçar a remoção de um nó do cluster
// Use este comando se o nó não puder ser removido normalmente
cluster.forceQuorumUsingPartitionOf('myorcl2:3306')

// Recuperar o quorum do cluster manualmente
// Use este comando se o cluster perder o quorum e precisar ser restaurado
cluster.forceQuorumUsingPartitionOf('myorcl2:3306')

// Verificar o quorum do cluster
cluster.status().defaultReplicaSet.quorumStatus

// Reconfigurar o cluster para tolerar falhas adicionais
// Exemplo: Configurar o cluster para tolerar até 2 falhas
cluster.setOption('memberWeight', 2)

// Atualizar a configuração de replicação do cluster
// Use este comando após alterações na configuração de rede ou replicação
cluster.rescan()

// Verificar o histórico de eventos do cluster
// Isso exibe eventos importantes, como falhas de nós ou mudanças de estado
cluster.status({extended: true}).defaultReplicaSet.events

// Verificar o atraso de replicação de um nó específico
// Isso ajuda a identificar problemas de desempenho na replicação
cluster.status({extended: true}).defaultReplicaSet.topology&#x5B;'myorcl3:3306'].replicationLag

// Verificar o papel de cada nó no cluster
// Isso exibe se o nó é primário ou secundário
cluster.status().defaultReplicaSet.topology&#x5B;'myorcl3:3306'].memberRole

// Verificar o modo de operação de cada nó
// Isso exibe se o nó está em modo de leitura/escrita (R/W) ou somente leitura (R/O)
cluster.status().defaultReplicaSet.topology&#x5B;'myorcl3:3306'].mode
</pre></div>


<p>E ainda temos nosso melhor amigo para monitorar MySQL, o <a href="https://github.com/charles-001/dolphie" target="_blank" rel="noreferrer noopener">Dolphie</a>:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img alt="" decoding="async" src="https://acaciolrdba.wordpress.com/wp-content/uploads/2024/12/image-1.png?w=1024" alt="" class="wp-image-1112"/><figcaption class="wp-element-caption">Esse aqui foi em um sandbox, mas é um bom exemplo 😆</figcaption></figure></div>


<h2 class="wp-block-heading">Referencias para estudos</h2>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img alt="" decoding="async" src="https://acaciolrdba.wordpress.com/wp-content/uploads/2024/12/image-2.png?w=604" alt="" class="wp-image-1116" style="width:770px;height:auto"/></figure></div>


<p>Espero que tenham curtido, se tiverem algum sugestão manda bala, posta ai nos comentarios e nos vemos ou nos falamos por ai. 🤘🏾🤘🏾</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>InnoDB Cluster &#8211; One command</title>
		<link>https://furushima.com.br/blog/innodb-cluster-one-command/</link>
		
		<dc:creator><![CDATA[Acacio Lima Rocha]]></dc:creator>
		<pubDate>Thu, 25 Sep 2025 20:04:09 +0000</pubDate>
				<category><![CDATA[MySQL]]></category>
		<guid isPermaLink="false">https://furushima.com.br/?p=2888</guid>

					<description><![CDATA[Neste post, eu vou compartilhar uma parada que achei bem legal, criar um processo automagico para implementar um InnoDB cluster no MySQL (este ambiente é apenas um sandbox, mas adaptei o script para um ambiente real [brinquem com o sandbox primeiro]). ⚠️ CONTÉM TEXTO MELHORADO POR AI – E TA TUDO BEM (SE SOUBER USAR [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="has-black-color has-text-color has-link-color wp-elements-bdcee45699c5ec3a3806611a13e9ca1d">Neste post, eu vou compartilhar uma parada que achei bem legal, criar um processo automagico para implementar um InnoDB cluster no MySQL (este ambiente é apenas um sandbox, mas adaptei o script para um ambiente real [brinquem com o sandbox primeiro]).</p>



<p class="has-vivid-red-color has-text-color has-link-color wp-elements-97f38820eb6ad89bfb13592df938e187"><strong>⚠️ CONTÉM TEXTO MELHORADO POR AI – E TA TUDO BEM (SE SOUBER USAR 🤭)⚠️</strong></p>



<p>Já de cara vou resumir o &#8220;One command&#8221;, é esse carinha aqui:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
mysqlsh --uri root:Welcome1@localhost:3306 --file=&quot;C:\Users\dbabrabo-666\Documents\ACACIOLR-DBA\mysql_full_innodb_cluster_w_replica_setup_mb_v4.js&quot; --log-level=8 --log-file=&quot;C:\temp\cluster_setup.log&quot;
</pre></div>


<p>Só que&#8230; tem um pancada de comandos de <em>javascript</em> a se considerar na criação do código para poder rodar apenas 1 linha de comando, sorry 😆</p>



<p class="has-large-font-size"><strong>BORA LA..:</strong></p>



<h1 class="wp-block-heading">Configurações do MySQL InnoDB Cluster</h1>



<h2 class="wp-block-heading">Configurações Gerais</h2>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Parâmetro</th><th>Valor</th></tr></thead><tbody><tr><td><strong>Nome do Cluster</strong></td><td>my-cluster-db-v5</td></tr><tr><td><strong>Senha Root</strong></td><td>Welcome1</td></tr><tr><td><strong>Diretório Sandbox</strong></td><td>C:\Users\dbabrabo-666\MySQL\mysql-sandboxes</td></tr><tr><td><strong>Usuário de Replicação</strong></td><td>repl</td></tr><tr><td><strong>Senha de Replicação</strong></td><td>Welcome1</td></tr><tr><td><strong>Modo do Cluster</strong></td><td>Single-Primary</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">Instâncias Primárias</h2>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Porta</th><th>Tipo</th><th>Peso</th><th>Prioridade</th><th>Status</th></tr></thead><tbody><tr><td>3307</td><td>Primary</td><td>100</td><td>Alta</td><td>Master</td></tr><tr><td>3310</td><td>Secondary</td><td>60</td><td>Média-Alta</td><td>Slave</td></tr><tr><td>3320</td><td>Secondary</td><td>40</td><td>Média</td><td>Slave</td></tr><tr><td>3330</td><td>Secondary</td><td>20</td><td>Baixa</td><td>Slave</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">Réplicas de Leitura (1:1 Mapping)</h2>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Porta Réplica</th><th>Porta Fonte</th><th>Label</th><th>Função</th></tr></thead><tbody><tr><td>3340</td><td>3307</td><td>Replica_Primary_3307</td><td>Read Replica do Master</td></tr><tr><td>3350</td><td>3310</td><td>Replica_Secondary_3310</td><td>Read Replica do Secondary</td></tr><tr><td>3360</td><td>3320</td><td>Replica_Tertiary_3320</td><td>Read Replica do Tertiary</td></tr><tr><td>3370</td><td>3330</td><td>Replica_Quaternary_3330</td><td>Read Replica do Quaternary</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">Timeouts de Configuração</h2>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Operação</th><th>Tempo (segundos)</th><th>Descrição</th></tr></thead><tbody><tr><td><strong>Criação do Cluster</strong></td><td>30</td><td>Tempo para estabilização inicial</td></tr><tr><td><strong>Adição de Instância</strong></td><td>15</td><td>Timeout para adicionar instância</td></tr><tr><td><strong>Estabilização</strong></td><td>10</td><td>Aguardo entre operações</td></tr><tr><td><strong>Recuperação</strong></td><td>5</td><td>Tempo para operações de recovery</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">Portas Utilizadas</h2>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Faixa</th><th>Portas</th><th>Quantidade</th><th>Uso</th></tr></thead><tbody><tr><td><strong>3307-3330</strong></td><td>3307, 3310, 3320, 3330</td><td>4</td><td>Instâncias Primárias</td></tr><tr><td><strong>3340-3370</strong></td><td>3340, 3350, 3360, 3370</td><td>4</td><td>Réplicas de Leitura</td></tr><tr><td><strong>Total</strong></td><td>8 portas</td><td>8</td><td>Todas as instâncias</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">Configurações de Segurança</h2>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Parâmetro</th><th>Valor</th><th>Descrição</th></tr></thead><tbody><tr><td><strong>Método de Recovery</strong></td><td>clone</td><td>Método para sincronização</td></tr><tr><td><strong>Força na Criação</strong></td><td>true</td><td>Força criação mesmo com conflitos</td></tr><tr><td><strong>Força na Dissolução</strong></td><td>true</td><td>Força remoção em caso de erro</td></tr><tr><td><strong>Restart Automático</strong></td><td>false</td><td>Não reinicia automaticamente</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">Recursos de Monitoramento</h2>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Recurso</th><th>Descrição</th></tr></thead><tbody><tr><td><strong>Log File</strong></td><td>C:\temp\cluster_setup.log</td></tr><tr><td><strong>Log Level</strong></td><td>8 (Debug completo)</td></tr><tr><td><strong>Status Extended</strong></td><td>Informações detalhadas do cluster</td></tr><tr><td><strong>Health Check</strong></td><td>Verificação automática de saúde</td></tr><tr><td><strong>Connectivity Test</strong></td><td>Teste de conectividade por porta</td></tr></tbody></table></figure>



<p><strong>Processo de Execução:</strong></p>



<ol class="wp-block-list">
<li><strong>Limpeza completa</strong> &#8211; Remove clusters e instâncias existentes</li>



<li><strong>Criação das primárias</strong> &#8211; Deploy de 4 instâncias sandbox MySQL</li>



<li><strong>Configuração</strong> &#8211; Prepara instâncias para clustering</li>



<li><strong>Criação do cluster</strong> &#8211; Estabelece cluster InnoDB com modo single-primary</li>



<li><strong>Adição de secundárias</strong> &#8211; Inclui as 3 instâncias restantes no cluster</li>



<li><strong>Configuração de pesos</strong> &#8211; Define prioridades (3307=100, 3310=60, 3320=40, 3330=20)</li>



<li><strong>Configuração de réplicas</strong> &#8211; Cria réplicas de leitura com replicação assíncrona</li>



<li><strong>Verificação final</strong> &#8211; Testa conectividade e exibe status completo</li>
</ol>



<p><strong>Recursos de Segurança:</strong></p>



<ul class="wp-block-list">
<li>Tratamento robusto de erros com limpeza automática</li>



<li>Verificação de saúde das instâncias</li>



<li>Sistema de retry para conexões</li>



<li>Limpeza de emergência em caso de falha crítica</li>



<li>Logs detalhados com códigos de status visuais</li>
</ul>



<p>O script é executado via MySQL Shell e cria uma infraestrutura completa de alta disponibilidade para MySQL em ambiente Windows pelo sandbox, nada de rodar em PRD.</p>



<p class="has-large-font-size">Versão do script para windows:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
// ============================================================================================
// MYSQL INNODB CLUSTER - PRODUCTION READY SETUP
// 4-NODE CLUSTER WITH 1:1 READ REPLICAS
// COMPLETE CLEANUP + VERIFICATION + ERROR HANDLING
// mysqlsh --uri root:Welcome1@localhost:3306 --file=&quot;C:\Users\dbabrabo-666\Documents\ACACIOLR-DBA\mysql_full_innodb_cluster_w_replica_setup_mb_v5.js&quot; --log-level=8 --log-file=&quot;C:\temp\cluster_setup.log&quot;
// \source C:\Users\dbabrabo-666\Documents\ACACIOLR-DBA\mysql_full_innodb_cluster_w_replica_setup_mb_v5.js
// mysqlsh --uri root@localhost:3307 --execute=&quot;$(cat C:\Users\dbabrabo-666\Documents\ACACIOLR-DBA\mysql_full_innodb_cluster_w_replica_setup_mb_v5.js)&quot;
// =================================================
// COMANDOS PARA MONITORAMENTO DE LOGS (POWERSHELL)
// =================================================
/*
// 1. Monitoramento contínuo com highlight de erros
Get-Content -Path &quot;C:\temp\cluster_setup.log&quot; -Wait | 
    ForEach-Object {
        if ($_ -match &quot;ERROR|FAIL|❌&quot;) { Write-Host $_ -ForegroundColor Red }
        elseif ($_ -match &quot;WARN|⚠️&quot;) { Write-Host $_ -ForegroundColor Yellow }
        else { Write-Host $_ }
    }
*/
/*
// 2. Monitoramento eficiente para logs grandes
$file = &quot;C:\temp\cluster_setup.log&quot;
$reader = &#x5B;System.IO.File]::OpenText($file)
$reader.BaseStream.Seek(0, &#x5B;System.IO.SeekOrigin]::End) | Out-Null
while ($true) {
    if ($reader.BaseStream.Length -gt $reader.BaseStream.Position) {
        $line = $reader.ReadLine()
        Write-Output $line
    }
    Start-Sleep -Milliseconds 200
}
*/
/*
// 3. Visualizar as últimas 10 linhas do log
Get-Content -Path &quot;C:\temp\cluster_setup.log&quot; -Tail 10
*/
// Configuration Constants
const CONFIG = {
  ports: &#x5B;3307, 3310, 3320, 3330, 3340, 3350, 3360, 3370],
  primaryPorts: &#x5B;3307, 3310, 3320, 3330],
  replicaPorts: &#x5B;3340, 3350, 3360, 3370],
  password: 'Welcome1',
  clusterName: 'my-cluster-db-v5',
  sandboxPath: 'C:\\Users\\dbabrabo-666\\MySQL\\mysql-sandboxes',
  replicationUser: {
    username: 'repl',
    password: 'Welcome1'
  },
  weights: {
    3307: 100,
    3310: 60,
    3320: 40,
    3330: 20
  },
  timeouts: {
    clusterCreation: 30,
    instanceAdd: 15,
    stabilization: 10,
    recovery: 5
  }
};
const firstPrimaryPort = CONFIG.primaryPorts&#x5B;0];
// Replica mapping (1:1 relationship)
const REPLICA_MAPPING = &#x5B;
  { port: 3340, source: 3307, label: 'Replica_Primary_3307' },
  { port: 3350, source: 3310, label: 'Replica_Secondary_3310' },
  { port: 3360, source: 3320, label: 'Replica_Tertiary_3320' },
  { port: 3370, source: 3330, label: 'Replica_Quaternary_3330' }
];
// Utility Functions
function printPhase(phase, description) {
  const separator = '='.repeat(80);
  print(`\n${separator}`);
  print(`PHASE ${phase}: ${description.toUpperCase()}`);
  print(`${separator}`);
}
function printSuccess(message) {
  print(`✅ ${message}`);
}
function printWarning(message) {
  print(`⚠️  ${message}`);
}
function printError(message) {
  print(`❌ ${message}`);
}
function printInfo(message) {
  print(`ℹ️  ${message}`);
}
function sleep(seconds) {
  print(`⏳ Aguardando ${seconds} segundos...`);
  os.sleep(seconds);
}
function waitForInstanceReady(port, maxRetries = 10) {
  let retries = 0;
  while (retries &lt; maxRetries) {
    try {
      const testSession = mysql.getSession(`root:${CONFIG.password}@localhost:${port}`);
      testSession.runSql(&quot;SELECT 1&quot;);
      testSession.close();
      return true;
    } catch (e) {
      retries++;
      print(`   Tentativa ${retries}/${maxRetries} - Aguardando instância ${port}...`);
      sleep(2);
    }
  }
  return false;
}
function checkClusterHealth(cluster) {
  try {
    const status = cluster.status();
    const healthy = status.defaultReplicaSet.status === 'OK';
    printInfo(`Status do cluster: ${status.defaultReplicaSet.status}`);
    return healthy;
  } catch (e) {
    printWarning(`Erro ao verificar saúde do cluster: ${e.message}`);
    return false;
  }
}
function safeKillSandbox(port) {
  try {
    dba.killSandboxInstance(port);
    printInfo(`Instância ${port} encerrada`);
  } catch (e) {
    // Ignora erros comuns de sandbox não existente
    if (e.message.includes(&quot;Unable to find pid file&quot;) || 
        e.message.includes(&quot;does not exist&quot;) ||
        e.message.includes(&quot;not found&quot;)) {
      printWarning(`Instância ${port} não estava ativa ou não existe`);
    } else {
      printWarning(`Erro ao encerrar ${port}: ${e.message}`);
    }
  }
}
function safeDeleteSandbox(port) {
  try {
    dba.deleteSandboxInstance(port);
    printInfo(`Instância ${port} removida`);
  } catch (e) {
    // Ignora erros comuns de sandbox não existente
    if (e.message.includes(&quot;does not exist&quot;) || 
        e.message.includes(&quot;not found&quot;)) {
      printWarning(`Instância ${port} não existe para remoção`);
    } else {
      printWarning(`Erro ao remover ${port}: ${e.message}`);
    }
  }
}
function safeCleanDirectories() {
  try {
    // Usar comando simples e seguro para Windows
    const command = `if exist &quot;${CONFIG.sandboxPath}&quot; rmdir /s /q &quot;${CONFIG.sandboxPath}&quot;`;
    // Tentar executar o comando de forma segura
    print(`Executando: ${command}`);
    // Como shell.runCmd pode ter problemas, vamos apenas informar
    printInfo(&quot;Comando de limpeza preparado - execute manualmente se necessário&quot;);
    printSuccess(&quot;Preparação de limpeza de diretórios concluída&quot;);
  } catch (e) {
    printWarning(`Não foi possível limpar diretórios automaticamente: ${e.message}`);
    printInfo(`Execute manualmente: rmdir /s /q &quot;${CONFIG.sandboxPath}&quot;`);
  }
}
// Main execution wrapped in try-catch
try {
  
  // ==============================================
  // PHASE 0: COMPREHENSIVE CLEANUP
  // ==============================================
  printPhase(0, &quot;LIMPEZA COMPLETA DO AMBIENTE&quot;);
  
  try {
    // Dissolve existing cluster
    try {
      printInfo(&quot;Verificando cluster existente...&quot;);
      const existingCluster = dba.getCluster();
      if (existingCluster) {
        printInfo(&quot;Dissolvendo cluster existente...&quot;);
        existingCluster.dissolve({ force: true });
        printSuccess(&quot;Cluster existente dissolvido com sucesso&quot;);
        sleep(3);
      }
    } catch (e) {
      printWarning(`Nenhum cluster ativo encontrado: ${e.message}`);
    }
    
    // Kill and delete all sandbox instances with safe methods
    printInfo(&quot;Removendo todas as instâncias sandbox...&quot;);
    CONFIG.ports.forEach(port =&gt; {
      safeKillSandbox(port);
      safeDeleteSandbox(port);
    });
    
    // Clean sandbox directories safely
    safeCleanDirectories();
    
    sleep(CONFIG.timeouts.recovery);
    printSuccess(&quot;LIMPEZA CONCLUÍDA&quot;);
    
  } catch (cleanupErr) {
    printError(`Erro durante cleanup: ${cleanupErr.message}`);
    // Não abortar aqui, continuar com a criação
  }
  
  // ==============================================
  // PHASE 1: DEPLOY PRIMARY INSTANCES
  // ==============================================
  printPhase(1, &quot;CRIAÇÃO DAS INSTÂNCIAS PRIMÁRIAS&quot;);
  
  CONFIG.primaryPorts.forEach((port, index) =&gt; {
    try {
      printInfo(`Criando instância primária ${port}...`);
      
      // Configuração simplificada sem parâmetros problemáticos
      dba.deploySandboxInstance(port, { 
        password: CONFIG.password,
        sandboxDir: CONFIG.sandboxPath
      });
      
      // Wait for instance to be ready
      if (waitForInstanceReady(port)) {
        printSuccess(`Instância primária ${port} criada e pronta (${index + 1}/${CONFIG.primaryPorts.length})`);
      } else {
        throw new Error(`Instância ${port} não ficou pronta no tempo esperado`);
      }
      
      sleep(2);
    } catch (e) {
      if (e.message.includes(&quot;already exists&quot;)) {
        printWarning(`Instância ${port} já existe`);
      } else {
        printError(`Erro ao criar instância ${port}: ${e.message}`);
        throw e;
      }
    }
  });
  
  // ==============================================
  // PHASE 2: CONFIGURE PRIMARY INSTANCES
  // ==============================================
  printPhase(2, &quot;CONFIGURAÇÃO DAS INSTÂNCIAS PRIMÁRIAS&quot;);
  
  CONFIG.primaryPorts.forEach((port, index) =&gt; {
    try {
      printInfo(`Configurando instância ${port} para clustering...`);
      
      // Configuração simplificada
      dba.configureInstance(`root:${CONFIG.password}@localhost:${port}`, { 
        clusterAdmin: 'root',
        restart: false
      });
      
      printSuccess(`Instância ${port} configurada (${index + 1}/${CONFIG.primaryPorts.length})`);
      sleep(1);
    } catch (e) {
      printError(`Erro ao configurar instância ${port}: ${e.message}`);
      throw e;
    }
  });
  
  // ==============================================
  // PHASE 3: CLUSTER CREATION (SIMPLIFICADO)
  // ==============================================
  printPhase(3, &quot;CRIAÇÃO DO CLUSTER INNODB&quot;);
  
  let cluster;
  try {
    printInfo(`Conectando à instância primária (${firstPrimaryPort})...`);
    shell.connect(`root:${CONFIG.password}@localhost:${firstPrimaryPort}`);
    printSuccess(&quot;Conectado à instância primária&quot;);
    
    try {
      printInfo(`Verificando se cluster '${CONFIG.clusterName}' já existe...`);
      cluster = dba.getCluster(CONFIG.clusterName);
      printSuccess(`Cluster '${CONFIG.clusterName}' existente carregado`);
    } catch {
      printInfo(`Criando novo cluster '${CONFIG.clusterName}'...`);
      
      // Configuração básica e confiável para criação do cluster
      cluster = dba.createCluster(CONFIG.clusterName, {
        multiPrimary: false,
        force: true
      });
      
      printSuccess(`Cluster '${CONFIG.clusterName}' criado com sucesso`);
      printInfo(`Aguardando estabilização do cluster primário...`);
      sleep(CONFIG.timeouts.clusterCreation);
      
      // Verificar se o cluster está saudável
      if (checkClusterHealth(cluster)) {
        printSuccess(&quot;Cluster primário está funcionando corretamente&quot;);
      } else {
        printWarning(&quot;Cluster primário pode não estar completamente estável&quot;);
      }
    }
    
  } catch (e) {
    printError(`Erro na criação/carregamento do cluster: ${e.message}`);
    throw e;
  }
  
  // ==============================================
  // PHASE 4: ADD SECONDARY INSTANCES TO CLUSTER
  // ==============================================
  printPhase(4, &quot;ADIÇÃO DAS INSTÂNCIAS SECUNDÁRIAS&quot;);
  
  const secondaryPorts = CONFIG.primaryPorts.slice(1); // Remove first primary port
  
  secondaryPorts.forEach((port, index) =&gt; {
    try {
      printInfo(`Adicionando instância ${port} ao cluster...`);
      
      // Configuração simplificada
      cluster.addInstance(`root:${CONFIG.password}@localhost:${port}`, {
        recoveryMethod: 'clone',
        waitRecovery: 2
      });
      
      printSuccess(`Instância ${port} adicionada ao cluster (${index + 1}/${secondaryPorts.length})`);
      
      // Verificar se a instância foi adicionada corretamente
      sleep(3);
      try {
        const status = cluster.status();
        const instanceStatus = status.defaultReplicaSet.topology&#x5B;`127.0.0.1:${port}`];
        if (instanceStatus &amp;&amp; instanceStatus.status === 'ONLINE') {
          printSuccess(`Instância ${port} está ONLINE no cluster`);
        } else {
          printWarning(`Instância ${port} pode não estar completamente sincronizada`);
        }
      } catch (statusErr) {
        printWarning(`Erro ao verificar status da instância ${port}: ${statusErr.message}`);
      }
      
    } catch (e) {
      printError(`Erro ao adicionar instância ${port}: ${e.message}`);
      // Não lançar erro para permitir continuar com outras instâncias
      printWarning(`Continuando com as próximas instâncias...`);
    }
  });
  
  printInfo(&quot;Aguardando sincronização completa do cluster...&quot;);
  sleep(CONFIG.timeouts.stabilization);
  
  // ==============================================
  // PHASE 5: CONFIGURE INSTANCE WEIGHTS
  // ==============================================
  printPhase(5, &quot;CONFIGURAÇÃO DE PESOS DAS INSTÂNCIAS&quot;);
  
  try {
    Object.entries(CONFIG.weights).forEach((&#x5B;port, weight]) =&gt; {
      try {
        cluster.setInstanceOption(`127.0.0.1:${port}`, 'memberWeight', weight);
        printSuccess(`Peso ${weight} configurado para instância ${port}`);
      } catch (e) {
        printWarning(`Erro ao configurar peso para ${port}: ${e.message}`);
      }
    });
    printSuccess(&quot;Configuração de pesos concluída&quot;);
  } catch (e) {
    printWarning(`Erro geral na configuração de pesos: ${e.message}`);
  }
  
  // ==============================================
  // PHASE 6: DEPLOY AND CONFIGURE READ REPLICAS
  // ==============================================
  printPhase(6, &quot;CONFIGURAÇÃO DAS RÉPLICAS DE LEITURA&quot;);
  
  REPLICA_MAPPING.forEach((replica, index) =&gt; {
    try {
      printInfo(`Processando réplica ${replica.port} para fonte ${replica.source}...`);
      
      // Deploy replica instance with simplified config
      printInfo(`- Criando instância réplica ${replica.port}...`);
      dba.deploySandboxInstance(replica.port, { 
        password: CONFIG.password,
        sandboxDir: CONFIG.sandboxPath
      });
      
      // Wait for replica to be ready
      if (!waitForInstanceReady(replica.port)) {
        throw new Error(`Réplica ${replica.port} não ficou pronta`);
      }
      
      // Configure replica instance
      printInfo(`- Configurando instância réplica ${replica.port}...`);
      dba.configureInstance(`root:${CONFIG.password}@localhost:${replica.port}`, { 
        clusterAdmin: 'root',
        restart: false
      });
      
      // Create replication user on source
      printInfo(`- Criando usuário de replicação na fonte ${replica.source}...`);
      const sourceSession = mysql.getSession(`root:${CONFIG.password}@localhost:${replica.source}`);
      sourceSession.runSql(`CREATE USER IF NOT EXISTS '${CONFIG.replicationUser.username}'@'%' IDENTIFIED BY '${CONFIG.replicationUser.password}'`);
      sourceSession.runSql(`GRANT REPLICATION SLAVE ON *.* TO '${CONFIG.replicationUser.username}'@'%'`);
      sourceSession.runSql(`GRANT BACKUP_ADMIN ON *.* TO '${CONFIG.replicationUser.username}'@'%'`);
      sourceSession.runSql(&quot;FLUSH PRIVILEGES&quot;);
      sourceSession.close();
      
      sleep(3);
      
      // Add as read replica to cluster with simplified config
      printInfo(`- Adicionando ${replica.port} como réplica de leitura...`);
      cluster.addReplicaInstance(`root:${CONFIG.password}@localhost:${replica.port}`, {
        label: replica.label,
        recoveryMethod: 'clone'
      });
      
      printSuccess(`Réplica ${replica.port} configurada para fonte ${replica.source} (${index + 1}/${REPLICA_MAPPING.length})`);
      sleep(CONFIG.timeouts.recovery);
      
    } catch (e) {
      printError(`Erro na configuração da réplica ${replica.port}: ${e.message}`);
      
      // Cleanup failed replica
      try {
        cluster.removeInstance(`root@localhost:${replica.port}`, { force: true });
        safeKillSandbox(replica.port);
        safeDeleteSandbox(replica.port);
        printInfo(`Limpeza da réplica ${replica.port} concluída`);
      } catch (cleanupErr) {
        printWarning(`Erro na limpeza da réplica ${replica.port}: ${cleanupErr.message}`);
      }
    }
  });
  
  // ==============================================
  // PHASE 7: FINAL VERIFICATION AND STATUS
  // ==============================================
  printPhase(7, &quot;VERIFICAÇÃO FINAL E STATUS&quot;);
  
  try {
    printInfo(&quot;Aguardando estabilização final...&quot;);
    sleep(CONFIG.timeouts.stabilization);
    
    // STATUS DETALHADO DO CLUSTER
    print(&quot;\n📊 STATUS COMPLETO DO CLUSTER:&quot;);
    print(&quot;=&quot; + &quot;=&quot;.repeat(70));
    
    try {
      const clusterStatus = cluster.status({extended: true});
      print(JSON.stringify(clusterStatus, null, 2));
      
      // Análise do status
      const defaultReplicaSet = clusterStatus.defaultReplicaSet;
      print(`\n🎯 ANÁLISE DO STATUS:`);
      print(`• Status Geral: ${defaultReplicaSet.status}`);
      print(`• Modo: ${defaultReplicaSet.mode || 'Single-Primary'}`);
      print(`• SSL Mode: ${defaultReplicaSet.ssl || 'N/A'}`);
      
      // Contagem de instâncias por status
      const topology = defaultReplicaSet.topology;
      const statusCount = {};
      Object.values(topology).forEach(instance =&gt; {
        const status = instance.status;
        statusCount&#x5B;status] = (statusCount&#x5B;status] || 0) + 1;
      });
      
      print(`\n📊 RESUMO POR STATUS:`);
      Object.entries(statusCount).forEach((&#x5B;status, count]) =&gt; {
        print(`• ${status}: ${count} instância(s)`);
      });
      
    } catch (e) {
      printError(`Erro ao obter status do cluster: ${e.message}`);
    }
    
    // TESTE DE CONECTIVIDADE
    print(&quot;\n🔗 TESTE DE CONECTIVIDADE:&quot;);
    print(&quot;=&quot; + &quot;=&quot;.repeat(70));
    CONFIG.primaryPorts.forEach(port =&gt; {
      try {
        const testSession = mysql.getSession(`root:${CONFIG.password}@localhost:${port}`);
        const result = testSession.runSql(&quot;SELECT @@hostname, @@port, @@server_id&quot;);
        const row = result.fetchOne();
        printSuccess(`Porta ${port}: Conectividade OK - Server ID: ${row&#x5B;2]}`);
        testSession.close();
      } catch (e) {
        printError(`Porta ${port}: Erro de conectividade - ${e.message}`);
      }
    });
    
  } catch (e) {
    printWarning(`Erro na verificação final: ${e.message}`);
  }
  
  // ==============================================
  // FINAL SUMMARY
  // ==============================================
  print(&quot;\n&quot; + &quot;🎉&quot;.repeat(80));
  print(&quot;CONFIGURAÇÃO CONCLUÍDA COM SUCESSO!&quot;);
  print(&quot;🎉&quot;.repeat(80));
  
  print(&quot;\n📋 RESUMO DA CONFIGURAÇÃO:&quot;);
  print(&quot;-&quot;.repeat(70));
  print(`• Cluster Name: ${CONFIG.clusterName}`);
  print(`• Instâncias Primárias: ${CONFIG.primaryPorts.length} (${CONFIG.primaryPorts.join(', ')})`);
  print(`• Réplicas de Leitura: ${REPLICA_MAPPING.length} (${REPLICA_MAPPING.map(r =&gt; r.port).join(', ')})`);
  print(`• Total de Instâncias: ${CONFIG.ports.length}`);
  print(`• Arquitetura: 4-Node Primary + 4 Read Replicas (1:1)`);
  
  print(&quot;\n🔗 MAPEAMENTO DE RÉPLICAS:&quot;);
  print(&quot;-&quot;.repeat(70));
  REPLICA_MAPPING.forEach(replica =&gt; {
    print(`• ${replica.source} → ${replica.port} (${replica.label})`);
  });
  
  print(&quot;\n⚖️  PESOS CONFIGURADOS:&quot;);
  print(&quot;-&quot;.repeat(70));
  Object.entries(CONFIG.weights).forEach((&#x5B;port, weight]) =&gt; {
    print(`• Porta ${port}: Peso ${weight}`);
  });
  
  print(&quot;\n🚀 PRÓXIMOS PASSOS:&quot;);
  print(&quot;-&quot;.repeat(70));
  print(&quot;• Configurar MySQL Router para balanceamento de carga&quot;);
  print(&quot;• Implementar monitoramento e alertas&quot;);
  print(&quot;• Configurar backups automatizados&quot;);
  print(&quot;• Testar failover e recuperação&quot;);
  print(&quot;• Ajustar configurações de performance conforme necessário&quot;);
  
  print(&quot;\n💡 COMANDOS ÚTEIS:&quot;);
  print(&quot;-&quot;.repeat(70));
  print(&quot;• Status do cluster: cluster.status({extended: true})&quot;);
  print(&quot;• Conectar ao cluster: shell.connect('root@localhost:3307')&quot;);
  print(`• Obter cluster: dba.getCluster('${CONFIG.clusterName}')`);
  print(&quot;• Rescan do cluster: cluster.rescan()&quot;);
  
  printSuccess(&quot;Script executado com sucesso!&quot;);
} catch (mainErr) {
  // ==============================================
  // EMERGENCY ERROR HANDLING
  // ==============================================
  print(&quot;\n&quot; + &quot;🚨&quot;.repeat(80));
  print(&quot;ERRO CRÍTICO DETECTADO - INICIANDO LIMPEZA DE EMERGÊNCIA&quot;);
  print(&quot;🚨&quot;.repeat(80));
  
  printError(`ERRO PRINCIPAL: ${mainErr.message}`);
  printError(`STACK TRACE: ${mainErr.stack || 'N/A'}`);
  
  printInfo(&quot;Executando limpeza de emergência...&quot;);
  
  try {
    // Emergency cluster dissolution
    try {
      const emergencyCluster = dba.getCluster();
      if (emergencyCluster) {
        emergencyCluster.dissolve({ force: true });
        printInfo(&quot;Cluster dissolvido durante limpeza de emergência&quot;);
      }
    } catch (e) {
      printWarning(`Erro ao dissolver cluster: ${e.message}`);
    }
    
    // Kill and delete all sandbox instances safely
    printInfo(&quot;Removendo todas as instâncias sandbox...&quot;);
    CONFIG.ports.forEach(port =&gt; {
      safeKillSandbox(port);
      safeDeleteSandbox(port);
    });
    
    // Safe directory cleanup
    safeCleanDirectories();
    
    printSuccess(&quot;Limpeza de emergência concluída&quot;);
    
  } catch (emergencyErr) {
    printError(`Erro durante limpeza de emergência: ${emergencyErr.message}`);
  }
  
  print(&quot;\n💡 SUGESTÕES PARA RESOLUÇÃO:&quot;);
  print(&quot;-&quot;.repeat(70));
  print(&quot;• Verifique se as portas estão disponíveis: netstat -an | findstr :330&quot;);
  print(&quot;• Confirme se o MySQL Shell tem permissões adequadas&quot;);
  print(&quot;• Verifique a conectividade de rede&quot;);
  print(&quot;• Analise os logs do MySQL para erros específicos&quot;);
  print(&quot;• Execute o script novamente após corrigir os problemas&quot;);
  print(&quot;• Verifique se há processos MySQL em execução: tasklist | findstr mysql&quot;);
  print(`• Limpe manualmente o diretório: rmdir /s /q &quot;${CONFIG.sandboxPath}&quot;`);
  
  // Re-throw the error for debugging
  throw mainErr;
}
</pre></div>


<p class="has-large-font-size"><strong>LOG &#8211; Output:</strong></p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
PS C:\Users\dbabrabo-666&gt; mysqlsh --uri root:Welcome1@localhost:3306 --file=&quot;C:\Users\dbabrabo-666\Documents\ACACIOLR-DBA\mysql_full_innodb_cluster_w_replica_setup_mb_v4.js&quot; --log-level=8 --log-file=&quot;C:\temp\cluster_setup.log&quot;
WARNING: Using a password on the command line interface can be insecure.
================================================================================PHASE 0: LIMPEZA COMPLETA DO AMBIENTE================================================================================ℹ️  Verificando cluster existente...⚠️  Nenhum cluster ativo encontrado: This function is not available through a session to a standalone instance (metadata exists, instance belongs to that metadata, but GR is not active)ℹ️  Removendo todas as instâncias sandbox...
Killing MySQL instance...
⚠️  Instância 3307 não estava ativa ou não existe
Deleting MySQL instance...
⚠️  Instância 3307 não existe para remoção
Killing MySQL instance...
⚠️  Instância 3310 não estava ativa ou não existe
Deleting MySQL instance...
⚠️  Instância 3310 não existe para remoção
Killing MySQL instance...
⚠️  Instância 3320 não estava ativa ou não existe
Deleting MySQL instance...
⚠️  Instância 3320 não existe para remoção
Killing MySQL instance...
⚠️  Instância 3330 não estava ativa ou não existe
Deleting MySQL instance...
⚠️  Instância 3330 não existe para remoção
Killing MySQL instance...
⚠️  Instância 3340 não estava ativa ou não existe
Deleting MySQL instance...
⚠️  Instância 3340 não existe para remoção
Killing MySQL instance...
⚠️  Instância 3350 não estava ativa ou não existe
Deleting MySQL instance...
⚠️  Instância 3350 não existe para remoção
Killing MySQL instance...
⚠️  Instância 3360 não estava ativa ou não existe
Deleting MySQL instance...
⚠️  Instância 3360 não existe para remoção
Killing MySQL instance...
⚠️  Instância 3370 não estava ativa ou não existe
Deleting MySQL instance...
⚠️  Instância 3370 não existe para remoçãoExecutando: if exist &quot;C:\Users\dbabrabo-666\MySQL\mysql-sandboxes&quot; rmdir /s /q &quot;C:\Users\dbabrabo-666\MySQL\mysql-sandboxes&quot;ℹ️  Comando de limpeza preparado - execute manualmente se necessário✅ Preparação de limpeza de diretórios concluída⏳ Aguardando 5 segundos...✅ LIMPEZA CONCLUÍDA
================================================================================PHASE 1: CRIAÇÃO DAS INSTÂNCIAS PRIMÁRIAS================================================================================ℹ️  Criando instância primária 3307...A new MySQL sandbox instance will be created on this host in
C:\Users\dbabrabo-666\MySQL\mysql-sandboxes\3307
Warning: Sandbox instances are only suitable for deploying and
running on your local machine for testing purposes and are not
accessible from external networks.
Deploying new MySQL instance...
Instance localhost:3307 successfully deployed and started.
Use shell.connect('root@localhost:3307') to connect to the instance.
✅ Instância primária 3307 criada e pronta (1/4)⏳ Aguardando 2 segundos...ℹ️  Criando instância primária 3310...A new MySQL sandbox instance will be created on this host in
C:\Users\dbabrabo-666\MySQL\mysql-sandboxes\3310
Warning: Sandbox instances are only suitable for deploying and
running on your local machine for testing purposes and are not
accessible from external networks.
Deploying new MySQL instance...
Instance localhost:3310 successfully deployed and started.
Use shell.connect('root@localhost:3310') to connect to the instance.
✅ Instância primária 3310 criada e pronta (2/4)⏳ Aguardando 2 segundos...ℹ️  Criando instância primária 3320...A new MySQL sandbox instance will be created on this host in
C:\Users\dbabrabo-666\MySQL\mysql-sandboxes\3320
Warning: Sandbox instances are only suitable for deploying and
running on your local machine for testing purposes and are not
accessible from external networks.
Deploying new MySQL instance...
Instance localhost:3320 successfully deployed and started.
Use shell.connect('root@localhost:3320') to connect to the instance.
✅ Instância primária 3320 criada e pronta (3/4)⏳ Aguardando 2 segundos...ℹ️  Criando instância primária 3330...A new MySQL sandbox instance will be created on this host in
C:\Users\dbabrabo-666\MySQL\mysql-sandboxes\3330
Warning: Sandbox instances are only suitable for deploying and
running on your local machine for testing purposes and are not
accessible from external networks.
Deploying new MySQL instance...
Instance localhost:3330 successfully deployed and started.
Use shell.connect('root@localhost:3330') to connect to the instance.
✅ Instância primária 3330 criada e pronta (4/4)⏳ Aguardando 2 segundos...
================================================================================PHASE 2: CONFIGURAÇÃO DAS INSTÂNCIAS PRIMÁRIAS================================================================================ℹ️  Configurando instância 3307 para clustering...Configuring local MySQL instance listening at port 3307 for use in an InnoDB Cluster...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.
This instance reports its own address as 127.0.0.1:3307
Assuming full account name 'root'@'%' for root
User 'root'@'%' already exists and will not be created.
applierWorkerThreads will be set to the default value of 4.
The instance '127.0.0.1:3307' is valid for InnoDB Cluster usage.
Successfully enabled parallel appliers.
✅ Instância 3307 configurada (1/4)⏳ Aguardando 1 segundos...ℹ️  Configurando instância 3310 para clustering...Configuring local MySQL instance listening at port 3310 for use in an InnoDB Cluster...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.
This instance reports its own address as 127.0.0.1:3310
Assuming full account name 'root'@'%' for root
User 'root'@'%' already exists and will not be created.
applierWorkerThreads will be set to the default value of 4.
The instance '127.0.0.1:3310' is valid for InnoDB Cluster usage.
Successfully enabled parallel appliers.
✅ Instância 3310 configurada (2/4)⏳ Aguardando 1 segundos...ℹ️  Configurando instância 3320 para clustering...Configuring local MySQL instance listening at port 3320 for use in an InnoDB Cluster...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.
This instance reports its own address as 127.0.0.1:3320
Assuming full account name 'root'@'%' for root
User 'root'@'%' already exists and will not be created.
applierWorkerThreads will be set to the default value of 4.
The instance '127.0.0.1:3320' is valid for InnoDB Cluster usage.
Successfully enabled parallel appliers.
✅ Instância 3320 configurada (3/4)⏳ Aguardando 1 segundos...ℹ️  Configurando instância 3330 para clustering...Configuring local MySQL instance listening at port 3330 for use in an InnoDB Cluster...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.
This instance reports its own address as 127.0.0.1:3330
Assuming full account name 'root'@'%' for root
User 'root'@'%' already exists and will not be created.
applierWorkerThreads will be set to the default value of 4.
The instance '127.0.0.1:3330' is valid for InnoDB Cluster usage.
Successfully enabled parallel appliers.
✅ Instância 3330 configurada (4/4)⏳ Aguardando 1 segundos...
================================================================================PHASE 3: CRIAÇÃO DO CLUSTER INNODB================================================================================ℹ️  Conectando à instância primária (3307)...✅ Conectado à instância primáriaℹ️  Verificando se cluster 'my-cluster-db-v5' já existe...ERROR: Command not available on an unmanaged standalone instance.
ℹ️  Criando novo cluster 'my-cluster-db-v5'...A new InnoDB Cluster will be created on instance '127.0.0.1:3307'.
Validating instance configuration at localhost:3307...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.
This instance reports its own address as 127.0.0.1:3307
Instance configuration is suitable.
NOTE: Group Replication will communicate with other members using '127.0.0.1:3307'. Use the localAddress option to override.
* Checking connectivity and SSL configuration...
Creating InnoDB Cluster 'my-cluster-db-v5' on '127.0.0.1:3307'...
Adding Seed Instance...
Cluster successfully created. Use Cluster.addInstance() to add MySQL instances.
At least 3 instances are needed for the cluster to be able to withstand up to
one server failure.
✅ Cluster 'my-cluster-db-v5' criado com sucessoℹ️  Aguardando estabilização do cluster primário...⏳ Aguardando 30 segundos...ℹ️  Status do cluster: OK_NO_TOLERANCE⚠️  Cluster primário pode não estar completamente estável
================================================================================PHASE 4: ADIÇÃO DAS INSTÂNCIAS SECUNDÁRIAS================================================================================ℹ️  Adicionando instância 3310 ao cluster...❌ Erro ao adicionar instância 3310: Argument #2: Invalid options: waitRecovery⚠️  Continuando com as próximas instâncias...ℹ️  Adicionando instância 3320 ao cluster...❌ Erro ao adicionar instância 3320: Argument #2: Invalid options: waitRecovery⚠️  Continuando com as próximas instâncias...ℹ️  Adicionando instância 3330 ao cluster...❌ Erro ao adicionar instância 3330: Argument #2: Invalid options: waitRecovery⚠️  Continuando com as próximas instâncias...ℹ️  Aguardando sincronização completa do cluster...⏳ Aguardando 10 segundos...
================================================================================PHASE 5: CONFIGURAÇÃO DE PESOS DAS INSTÂNCIAS================================================================================Setting the value of 'memberWeight' to '100' in the instance: '127.0.0.1:3307' ...
Successfully set the value of 'memberWeight' to '100' in the cluster member: '127.0.0.1:3307'.
✅ Peso 100 configurado para instância 3307⚠️  Erro ao configurar peso para 3310: The instance '127.0.0.1:3310' does not belong to the cluster.⚠️  Erro ao configurar peso para 3320: The instance '127.0.0.1:3320' does not belong to the cluster.⚠️  Erro ao configurar peso para 3330: The instance '127.0.0.1:3330' does not belong to the cluster.✅ Configuração de pesos concluída
================================================================================PHASE 6: CONFIGURAÇÃO DAS RÉPLICAS DE LEITURA================================================================================ℹ️  Processando réplica 3340 para fonte 3307...ℹ️  - Criando instância réplica 3340...A new MySQL sandbox instance will be created on this host in
C:\Users\dbabrabo-666\MySQL\mysql-sandboxes\3340
Warning: Sandbox instances are only suitable for deploying and
running on your local machine for testing purposes and are not
accessible from external networks.
Deploying new MySQL instance...
Instance localhost:3340 successfully deployed and started.
Use shell.connect('root@localhost:3340') to connect to the instance.
ℹ️  - Configurando instância réplica 3340...Configuring local MySQL instance listening at port 3340 for use in an InnoDB Cluster...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.
This instance reports its own address as 127.0.0.1:3340
Assuming full account name 'root'@'%' for root
User 'root'@'%' already exists and will not be created.
applierWorkerThreads will be set to the default value of 4.
The instance '127.0.0.1:3340' is valid for InnoDB Cluster usage.
Successfully enabled parallel appliers.
ℹ️  - Criando usuário de replicação na fonte 3307...⏳ Aguardando 3 segundos...ℹ️  - Adicionando 3340 como réplica de leitura...Setting up '127.0.0.1:3340' as a Read Replica of Cluster 'my-cluster-db-v5'.
Validating instance configuration at localhost:3340...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.
This instance reports its own address as 127.0.0.1:3340
Instance configuration is suitable.
* Checking transaction state of the instance...
NOTE: The target instance '127.0.0.1:3340' has not been pre-provisioned (GTID set is empty).
Clone based recovery selected through the recoveryMethod option
* Checking connectivity and SSL configuration...
Monitoring Clone based state recovery of the new member. Press ^C to abort the operation.
Clone based state recovery is now in progress.
NOTE: A server restart is expected to happen as part of the clone process. If the
server does not support the RESTART command or does not come back after a
while, you may need to manually start it back.
* Waiting for clone to finish...
NOTE: 127.0.0.1:3340 is being cloned from 127.0.0.1:3307
** Stage DROP DATA: Completed
** Clone Transfer
    FILE COPY  ############################################################  100%  Completed
    PAGE COPY  ============================================================    0%  In Progress
    REDO COPY  ============================================================    0%  Not Started
NOTE: 127.0.0.1:3340 is shutting down...
* Waiting for server restart... ready
* 127.0.0.1:3340 has restarted, waiting for clone to finish...
** Stage RESTART: Completed
* Clone process has finished: 74.95 MB transferred in about 1 second (~74.95 MB/s)
* Configuring Read-Replica managed replication channel...
** Changing replication source of 127.0.0.1:3340 to 127.0.0.1:3307
* Waiting for Read-Replica '127.0.0.1:3340' to synchronize with Cluster...
** Transactions replicated  ############################################################  100%
'127.0.0.1:3340' successfully added as a Read-Replica of Cluster 'my-cluster-db-v5'.
✅ Réplica 3340 configurada para fonte 3307 (1/4)⏳ Aguardando 5 segundos...ℹ️  Processando réplica 3350 para fonte 3310...ℹ️  - Criando instância réplica 3350...A new MySQL sandbox instance will be created on this host in
C:\Users\dbabrabo-666\MySQL\mysql-sandboxes\3350
Warning: Sandbox instances are only suitable for deploying and
running on your local machine for testing purposes and are not
accessible from external networks.
Deploying new MySQL instance...
Instance localhost:3350 successfully deployed and started.
Use shell.connect('root@localhost:3350') to connect to the instance.
ℹ️  - Configurando instância réplica 3350...Configuring local MySQL instance listening at port 3350 for use in an InnoDB Cluster...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.
This instance reports its own address as 127.0.0.1:3350
Assuming full account name 'root'@'%' for root
User 'root'@'%' already exists and will not be created.
applierWorkerThreads will be set to the default value of 4.
The instance '127.0.0.1:3350' is valid for InnoDB Cluster usage.
Successfully enabled parallel appliers.
ℹ️  - Criando usuário de replicação na fonte 3310...⏳ Aguardando 3 segundos...ℹ️  - Adicionando 3350 como réplica de leitura...Setting up '127.0.0.1:3350' as a Read Replica of Cluster 'my-cluster-db-v5'.
Validating instance configuration at localhost:3350...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.
This instance reports its own address as 127.0.0.1:3350
Instance configuration is suitable.
* Checking transaction state of the instance...
NOTE: The target instance '127.0.0.1:3350' has not been pre-provisioned (GTID set is empty).
Clone based recovery selected through the recoveryMethod option
* Checking connectivity and SSL configuration...
Monitoring Clone based state recovery of the new member. Press ^C to abort the operation.
Clone based state recovery is now in progress.
NOTE: A server restart is expected to happen as part of the clone process. If the
server does not support the RESTART command or does not come back after a
while, you may need to manually start it back.
* Waiting for clone to finish...
NOTE: 127.0.0.1:3350 is being cloned from 127.0.0.1:3307
** Stage DROP DATA: Completed
** Clone Transfer
    FILE COPY  ############################################################  100%  Completed
    PAGE COPY  ############################################################  100%  Completed
    REDO COPY  ############################################################  100%  Completed
NOTE: 127.0.0.1:3350 is shutting down...
* Waiting for server restart... ready
* 127.0.0.1:3350 has restarted, waiting for clone to finish...
** Stage RESTART: Completed
* Clone process has finished: 74.88 MB transferred in about 1 second (~74.88 MB/s)
* Configuring Read-Replica managed replication channel...
** Changing replication source of 127.0.0.1:3350 to 127.0.0.1:3307
* Waiting for Read-Replica '127.0.0.1:3350' to synchronize with Cluster...
** Transactions replicated  ############################################################  100%
'127.0.0.1:3350' successfully added as a Read-Replica of Cluster 'my-cluster-db-v5'.
✅ Réplica 3350 configurada para fonte 3310 (2/4)⏳ Aguardando 5 segundos...ℹ️  Processando réplica 3360 para fonte 3320...ℹ️  - Criando instância réplica 3360...A new MySQL sandbox instance will be created on this host in
C:\Users\dbabrabo-666\MySQL\mysql-sandboxes\3360
Warning: Sandbox instances are only suitable for deploying and
running on your local machine for testing purposes and are not
accessible from external networks.
Deploying new MySQL instance...
Instance localhost:3360 successfully deployed and started.
Use shell.connect('root@localhost:3360') to connect to the instance.
ℹ️  - Configurando instância réplica 3360...Configuring local MySQL instance listening at port 3360 for use in an InnoDB Cluster...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.
This instance reports its own address as 127.0.0.1:3360
Assuming full account name 'root'@'%' for root
User 'root'@'%' already exists and will not be created.
applierWorkerThreads will be set to the default value of 4.
The instance '127.0.0.1:3360' is valid for InnoDB Cluster usage.
Successfully enabled parallel appliers.
ℹ️  - Criando usuário de replicação na fonte 3320...⏳ Aguardando 3 segundos...ℹ️  - Adicionando 3360 como réplica de leitura...Setting up '127.0.0.1:3360' as a Read Replica of Cluster 'my-cluster-db-v5'.
Validating instance configuration at localhost:3360...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.
This instance reports its own address as 127.0.0.1:3360
Instance configuration is suitable.
* Checking transaction state of the instance...
NOTE: The target instance '127.0.0.1:3360' has not been pre-provisioned (GTID set is empty).
Clone based recovery selected through the recoveryMethod option
* Checking connectivity and SSL configuration...
Monitoring Clone based state recovery of the new member. Press ^C to abort the operation.
Clone based state recovery is now in progress.
NOTE: A server restart is expected to happen as part of the clone process. If the
server does not support the RESTART command or does not come back after a
while, you may need to manually start it back.
* Waiting for clone to finish...
NOTE: 127.0.0.1:3360 is being cloned from 127.0.0.1:3307
** Stage DROP DATA: Completed
** Clone Transfer
    FILE COPY  ############################################################  100%  Completed
    PAGE COPY  ############################################################  100%  Completed
    REDO COPY  ############################################################  100%  Completed
NOTE: 127.0.0.1:3360 is shutting down...
* Waiting for server restart... ready
* 127.0.0.1:3360 has restarted, waiting for clone to finish...
** Stage RESTART: Completed
* Clone process has finished: 74.89 MB transferred in about 1 second (~74.89 MB/s)
* Configuring Read-Replica managed replication channel...
** Changing replication source of 127.0.0.1:3360 to 127.0.0.1:3307
* Waiting for Read-Replica '127.0.0.1:3360' to synchronize with Cluster...
** Transactions replicated  ############################################################  100%
'127.0.0.1:3360' successfully added as a Read-Replica of Cluster 'my-cluster-db-v5'.
✅ Réplica 3360 configurada para fonte 3320 (3/4)⏳ Aguardando 5 segundos...ℹ️  Processando réplica 3370 para fonte 3330...ℹ️  - Criando instância réplica 3370...A new MySQL sandbox instance will be created on this host in
C:\Users\dbabrabo-666\MySQL\mysql-sandboxes\3370
Warning: Sandbox instances are only suitable for deploying and
running on your local machine for testing purposes and are not
accessible from external networks.
Deploying new MySQL instance...
Instance localhost:3370 successfully deployed and started.
Use shell.connect('root@localhost:3370') to connect to the instance.
ℹ️  - Configurando instância réplica 3370...Configuring local MySQL instance listening at port 3370 for use in an InnoDB Cluster...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.
This instance reports its own address as 127.0.0.1:3370
Assuming full account name 'root'@'%' for root
User 'root'@'%' already exists and will not be created.
applierWorkerThreads will be set to the default value of 4.
The instance '127.0.0.1:3370' is valid for InnoDB Cluster usage.
Successfully enabled parallel appliers.
ℹ️  - Criando usuário de replicação na fonte 3330...⏳ Aguardando 3 segundos...ℹ️  - Adicionando 3370 como réplica de leitura...Setting up '127.0.0.1:3370' as a Read Replica of Cluster 'my-cluster-db-v5'.
Validating instance configuration at localhost:3370...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.
This instance reports its own address as 127.0.0.1:3370
Instance configuration is suitable.
* Checking transaction state of the instance...
NOTE: The target instance '127.0.0.1:3370' has not been pre-provisioned (GTID set is empty).
Clone based recovery selected through the recoveryMethod option
* Checking connectivity and SSL configuration...
Monitoring Clone based state recovery of the new member. Press ^C to abort the operation.
Clone based state recovery is now in progress.
NOTE: A server restart is expected to happen as part of the clone process. If the
server does not support the RESTART command or does not come back after a
while, you may need to manually start it back.
* Waiting for clone to finish...
NOTE: 127.0.0.1:3370 is being cloned from 127.0.0.1:3307
** Stage DROP DATA: Completed
** Clone Transfer
    FILE COPY  ############################################################  100%  Completed
    PAGE COPY  ############################################################  100%  Completed
    REDO COPY  ############################################################  100%  Completed
* Clone process has finished: 74.89 MB transferred in about 1 second (~74.89 MB/s)
* Configuring Read-Replica managed replication channel...
** Changing replication source of 127.0.0.1:3370 to 127.0.0.1:3307
* Waiting for Read-Replica '127.0.0.1:3370' to synchronize with Cluster...
** Transactions replicated  ############################################################  100%
'127.0.0.1:3370' successfully added as a Read-Replica of Cluster 'my-cluster-db-v5'.
✅ Réplica 3370 configurada para fonte 3330 (4/4)⏳ Aguardando 5 segundos...
================================================================================PHASE 7: VERIFICAÇÃO FINAL E STATUS================================================================================ℹ️  Aguardando estabilização final...⏳ Aguardando 10 segundos...
📊 STATUS COMPLETO DO CLUSTER:======================================================================={
  &quot;clusterName&quot;: &quot;my-cluster-db-v5&quot;,
  &quot;defaultReplicaSet&quot;: {
    &quot;GRProtocolVersion&quot;: &quot;8.0.27&quot;,
    &quot;communicationStack&quot;: &quot;MYSQL&quot;,
    &quot;groupName&quot;: &quot;48fcdfde-4c7a-11f0-9ee3-18a59cb32d88&quot;,
    &quot;groupViewChangeUuid&quot;: &quot;AUTOMATIC&quot;,
    &quot;groupViewId&quot;: &quot;17502748550958043:1&quot;,
    &quot;name&quot;: &quot;default&quot;,
    &quot;paxosSingleLeader&quot;: &quot;OFF&quot;,
    &quot;primary&quot;: &quot;127.0.0.1:3307&quot;,
    &quot;ssl&quot;: &quot;REQUIRED&quot;,
    &quot;status&quot;: &quot;OK_NO_TOLERANCE&quot;,
    &quot;statusText&quot;: &quot;Cluster is NOT tolerant to any failures.&quot;,
    &quot;topology&quot;: {
      &quot;127.0.0.1:3307&quot;: {
        &quot;address&quot;: &quot;127.0.0.1:3307&quot;,
        &quot;applierWorkerThreads&quot;: 4,
        &quot;fenceSysVars&quot;: &#x5B;],
        &quot;memberId&quot;: &quot;215a2338-4c7a-11f0-8f41-18a59cb32d88&quot;,
        &quot;memberRole&quot;: &quot;PRIMARY&quot;,
        &quot;memberState&quot;: &quot;ONLINE&quot;,
        &quot;mode&quot;: &quot;R/W&quot;,
        &quot;readReplicas&quot;: {
          &quot;Replica_Primary_3307&quot;: {
            &quot;address&quot;: &quot;127.0.0.1:3340&quot;,
            &quot;applierStatus&quot;: &quot;APPLIED_ALL&quot;,
            &quot;applierThreadState&quot;: &quot;Waiting for an event from Coordinator&quot;,
            &quot;applierWorkerThreads&quot;: 4,
            &quot;receiverStatus&quot;: &quot;ON&quot;,
            &quot;receiverThreadState&quot;: &quot;Waiting for source to send event&quot;,
            &quot;replicationLag&quot;: &quot;applier_queue_applied&quot;,
            &quot;replicationSources&quot;: &#x5B;
              &quot;PRIMARY&quot;
            ],
            &quot;replicationSsl&quot;: &quot;TLS_AES_128_GCM_SHA256 TLSv1.3&quot;,
            &quot;role&quot;: &quot;READ_REPLICA&quot;,
            &quot;status&quot;: &quot;ONLINE&quot;,
            &quot;version&quot;: &quot;9.3.0&quot;
          },
          &quot;Replica_Quaternary_3330&quot;: {
            &quot;address&quot;: &quot;127.0.0.1:3370&quot;,
            &quot;applierStatus&quot;: &quot;APPLIED_ALL&quot;,
            &quot;applierThreadState&quot;: &quot;Waiting for an event from Coordinator&quot;,
            &quot;applierWorkerThreads&quot;: 4,
            &quot;receiverStatus&quot;: &quot;ON&quot;,
            &quot;receiverThreadState&quot;: &quot;Waiting for source to send event&quot;,
            &quot;replicationLag&quot;: &quot;applier_queue_applied&quot;,
            &quot;replicationSources&quot;: &#x5B;
              &quot;PRIMARY&quot;
            ],
            &quot;replicationSsl&quot;: &quot;TLS_AES_128_GCM_SHA256 TLSv1.3&quot;,
            &quot;role&quot;: &quot;READ_REPLICA&quot;,
            &quot;status&quot;: &quot;ONLINE&quot;,
            &quot;version&quot;: &quot;9.3.0&quot;
          },
          &quot;Replica_Secondary_3310&quot;: {
            &quot;address&quot;: &quot;127.0.0.1:3350&quot;,
            &quot;applierStatus&quot;: &quot;APPLIED_ALL&quot;,
            &quot;applierThreadState&quot;: &quot;Waiting for an event from Coordinator&quot;,
            &quot;applierWorkerThreads&quot;: 4,
            &quot;receiverStatus&quot;: &quot;ON&quot;,
            &quot;receiverThreadState&quot;: &quot;Waiting for source to send event&quot;,
            &quot;replicationLag&quot;: &quot;applier_queue_applied&quot;,
            &quot;replicationSources&quot;: &#x5B;
              &quot;PRIMARY&quot;
            ],
            &quot;replicationSsl&quot;: &quot;TLS_AES_128_GCM_SHA256 TLSv1.3&quot;,
            &quot;role&quot;: &quot;READ_REPLICA&quot;,
            &quot;status&quot;: &quot;ONLINE&quot;,
            &quot;version&quot;: &quot;9.3.0&quot;
          },
          &quot;Replica_Tertiary_3320&quot;: {
            &quot;address&quot;: &quot;127.0.0.1:3360&quot;,
            &quot;applierStatus&quot;: &quot;APPLIED_ALL&quot;,
            &quot;applierThreadState&quot;: &quot;Waiting for an event from Coordinator&quot;,
            &quot;applierWorkerThreads&quot;: 4,
            &quot;receiverStatus&quot;: &quot;ON&quot;,
            &quot;receiverThreadState&quot;: &quot;Waiting for source to send event&quot;,
            &quot;replicationLag&quot;: &quot;applier_queue_applied&quot;,
            &quot;replicationSources&quot;: &#x5B;
              &quot;PRIMARY&quot;
            ],
            &quot;replicationSsl&quot;: &quot;TLS_AES_128_GCM_SHA256 TLSv1.3&quot;,
            &quot;role&quot;: &quot;READ_REPLICA&quot;,
            &quot;status&quot;: &quot;ONLINE&quot;,
            &quot;version&quot;: &quot;9.3.0&quot;
          }
        },
        &quot;replicationLag&quot;: &quot;applier_queue_applied&quot;,
        &quot;role&quot;: &quot;HA&quot;,
        &quot;status&quot;: &quot;ONLINE&quot;,
        &quot;version&quot;: &quot;9.3.0&quot;
      }
    },
    &quot;topologyMode&quot;: &quot;Single-Primary&quot;
  },
  &quot;groupInformationSourceMember&quot;: &quot;127.0.0.1:3307&quot;,
  &quot;metadataVersion&quot;: &quot;2.3.0&quot;
}
🎯 ANÁLISE DO STATUS:• Status Geral: OK_NO_TOLERANCE• Modo: Single-Primary• SSL Mode: REQUIRED
📊 RESUMO POR STATUS:• ONLINE: 1 instância(s)
🔗 TESTE DE CONECTIVIDADE:=======================================================================✅ Porta 3307: Conectividade OK - Server ID: 3820020054✅ Porta 3310: Conectividade OK - Server ID: 3359029909✅ Porta 3320: Conectividade OK - Server ID: 1516761045✅ Porta 3330: Conectividade OK - Server ID: 272308050
🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉CONFIGURAÇÃO CONCLUÍDA COM SUCESSO!🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉
📋 RESUMO DA CONFIGURAÇÃO:----------------------------------------------------------------------• Cluster Name: my-cluster-db-v5• Instâncias Primárias: 4 (3307, 3310, 3320, 3330)• Réplicas de Leitura: 4 (3340, 3350, 3360, 3370)• Total de Instâncias: 8• Arquitetura: 4-Node Primary + 4 Read Replicas (1:1)
🔗 MAPEAMENTO DE RÉPLICAS:----------------------------------------------------------------------• 3307 → 3340 (Replica_Primary_3307)• 3310 → 3350 (Replica_Secondary_3310)• 3320 → 3360 (Replica_Tertiary_3320)• 3330 → 3370 (Replica_Quaternary_3330)
⚖️  PESOS CONFIGURADOS:----------------------------------------------------------------------• Porta 3307: Peso 100• Porta 3310: Peso 60• Porta 3320: Peso 40• Porta 3330: Peso 20
🚀 PRÓXIMOS PASSOS:----------------------------------------------------------------------• Configurar MySQL Router para balanceamento de carga• Implementar monitoramento e alertas• Configurar backups automatizados• Testar failover e recuperação• Ajustar configurações de performance conforme necessário
💡 COMANDOS ÚTEIS:----------------------------------------------------------------------• Status do cluster: cluster.status({extended: true})• Conectar ao cluster: shell.connect('root@localhost:3307')• Obter cluster: dba.getCluster('my-cluster-db-v5')• Rescan do cluster: cluster.rescan()✅ Script executado com sucesso!
PS C:\Users\dbabrabo-666&gt;
</pre></div>


<p class="has-large-font-size">Versão do script para Linux/macOS/Unix</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
// ============================================================================================
// MYSQL INNODB CLUSTER - ENTERPRISE PRODUCTION SETUP
// 4-NODE CLUSTER WITH 1:1 READ REPLICAS
// COMPLETE CLEANUP + VERIFICATION + ERROR HANDLING
// ============================================================================================
// 
// DESCRIÇÃO:
//   Script automatizado para criar um cluster MySQL InnoDB com 4 nós primários e 4 réplicas
//   de leitura (1:1). Inclui limpeza completa, validação e tratamento de erros.
//
// REQUISITOS:
//   - MySQL Shell 8.0+
//   - Sistema Operacional: Linux/macOS
//   - RAM: Mínimo 2GB livre
//   - Disco: Mínimo 5GB livre
//   - Portas: 3307-3370 devem estar livres
//
// AUTOR: Acacio LR - DBA
// ============================================================================================
// COMO USAR ESTE SCRIPT:
// ============================================================================================
//
// 1. SALVAR O SCRIPT:
//    Salve este arquivo como 'mysql_innodb_cluster_macOS_mb.js' em seu diretório home:
//    $ nano ~/mysql_innodb_cluster_macOS_mb.js
//    (cole o conteúdo e salve com Ctrl+X, Y, Enter)
//
// 2. EXECUTAR O SCRIPT (escolha uma opção):
//
//    OPÇÃO A - Execução Simples:
//    $ mysqlsh --file ~/mysql_innodb_cluster_macOS_mb.js
//
//    OPÇÃO B - Com Log Detalhado:
//    $ mysqlsh --file mysql_innodb_cluster_macOS_mb.js --log-level=8 --log-file=/tmp/cluster.log
//
//    OPÇÃO C - Dentro do MySQL Shell:
//    $ mysqlsh
//    MySQL JS&gt; \source ~/mysql_innodb_cluster_macOS_mb.js
//
// 3. MONITORAR EXECUÇÃO (em outro terminal):
//    $ tail -f /tmp/cluster_setup.log
// 
// ============================================================================================

// Configuration Constants
const CONFIG = {
  ports: &#x5B;3307, 3310, 3320, 3330, 3340, 3350, 3360, 3370],
  primaryPorts: &#x5B;3307, 3310, 3320, 3330],
  replicaPorts: &#x5B;3340, 3350, 3360, 3370],
  password: 'Welcome1',
  clusterName: 'my-cluster-db-v5',
  sandboxPath: '/Users/acaciolr/mysql-sandboxes',
  replicationUser: {
    username: 'repl',
    password: 'Welcome1'
  },
  weights: {
    3307: 100,
    3310: 60,
    3320: 40,
    3330: 20
  },
  timeouts: {
    clusterCreation: 30,
    instanceAdd: 20,
    stabilization: 15,
    recovery: 10
  }
};

const firstPrimaryPort = CONFIG.primaryPorts&#x5B;0];

// Replica mapping (1:1 relationship)
const REPLICA_MAPPING = &#x5B;
  { port: 3340, source: 3307, label: 'Replica_Primary_3307' },
  { port: 3350, source: 3310, label: 'Replica_Secondary_3310' },
  { port: 3360, source: 3320, label: 'Replica_Tertiary_3320' },
  { port: 3370, source: 3330, label: 'Replica_Quaternary_3330' }
];

// Utility Functions
function printPhase(phase, description) {
  const separator = '='.repeat(80);
  print(&quot;\n&quot; + separator);
  print(&quot;PHASE &quot; + phase + &quot;: &quot; + description.toUpperCase());
  print(separator + &quot;\n&quot;);
}

function printSuccess(message) {
  print(&quot;✅ &quot; + message);
}

function printWarning(message) {
  print(&quot;⚠️  &quot; + message);
}

function printError(message) {
  print(&quot;❌ &quot; + message);
}

function printInfo(message) {
  print(&quot;ℹ️  &quot; + message);
}

function sleep(seconds) {
  print(&quot;⏳ Aguardando &quot; + seconds + &quot; segundos...\n&quot;);
  os.sleep(seconds);
}

function waitForInstanceReady(port, maxRetries = 15) {
  let retries = 0;
  while (retries &amp;lt; maxRetries) {
    try {
      const testSession = mysql.getSession(&quot;root:&quot; + CONFIG.password + &quot;@localhost:&quot; + port);
      testSession.runSql(&quot;SELECT 1&quot;);
      testSession.close();
      return true;
    } catch (e) {
      retries++;
      print(&quot;   Tentativa &quot; + retries + &quot;/&quot; + maxRetries + &quot; - Aguardando instância &quot; + port + &quot;...&quot;);
      sleep(3);
    }
  }
  return false;
}

function checkClusterHealth(cluster) {
  try {
    const status = cluster.status();
    const healthy = status.defaultReplicaSet.status === 'OK' || 
                   status.defaultReplicaSet.status === 'OK_NO_TOLERANCE' ||
                   status.defaultReplicaSet.status === 'OK_PARTIAL';
    printInfo(&quot;Status do cluster: &quot; + status.defaultReplicaSet.status);
    return healthy;
  } catch (e) {
    printWarning(&quot;Erro ao verificar saúde do cluster: &quot; + e.message);
    return false;
  }
}

function safeKillSandbox(port) {
  try {
    dba.killSandboxInstance(port);
    printInfo(&quot;Instância &quot; + port + &quot; encerrada&quot;);
  } catch (e) {
    if (e.message.includes(&quot;Unable to find pid file&quot;) || 
        e.message.includes(&quot;does not exist&quot;) ||
        e.message.includes(&quot;not found&quot;)) {
      // Silently ignore if instance doesn't exist
    } else {
      printWarning(&quot;Erro ao encerrar &quot; + port + &quot;: &quot; + e.message);
    }
  }
}

function safeDeleteSandbox(port) {
  try {
    dba.deleteSandboxInstance(port);
    printInfo(&quot;Instância &quot; + port + &quot; removida&quot;);
  } catch (e) {
    if (e.message.includes(&quot;does not exist&quot;) || 
        e.message.includes(&quot;not found&quot;)) {
      // Silently ignore if instance doesn't exist
    } else {
      printWarning(&quot;Erro ao remover &quot; + port + &quot;: &quot; + e.message);
    }
  }
}

function safeCleanDirectories() {
  try {
    const command = &quot;rm -rf &quot; + CONFIG.sandboxPath;
    printInfo(&quot;Comando de limpeza preparado: &quot; + command);
    printSuccess(&quot;Preparação de limpeza de diretórios concluída&quot;);
  } catch (e) {
    printWarning(&quot;Não foi possível limpar diretórios automaticamente: &quot; + e.message);
    printInfo(&quot;Execute manualmente: rm -rf &quot; + CONFIG.sandboxPath);
  }
}

// Main execution wrapped in try-catch
try {
  
  // ==============================================
  // PHASE 0: COMPREHENSIVE CLEANUP
  // ==============================================
  printPhase(0, &quot;LIMPEZA COMPLETA DO AMBIENTE&quot;);
  
  try {
    // Dissolve existing cluster
    try {
      printInfo(&quot;Verificando cluster existente...&quot;);
      const existingCluster = dba.getCluster();
      if (existingCluster) {
        printInfo(&quot;Dissolvendo cluster existente...&quot;);
        existingCluster.dissolve({ force: true });
        printSuccess(&quot;Cluster existente dissolvido com sucesso\n&quot;);
        sleep(3);
      }
    } catch (e) {
      printWarning(&quot;Nenhum cluster ativo encontrado: Iniciando nova configuração\n&quot;);
    }
    
    // Kill and delete all sandbox instances
    printInfo(&quot;Removendo todas as instâncias sandbox...&quot;);
    CONFIG.ports.forEach(port =&gt; {
      safeKillSandbox(port);
    });
    
    print(&quot;&quot;); // Linha em branco
    
    CONFIG.ports.forEach(port =&gt; {
      safeDeleteSandbox(port);
    });
    
    print(&quot;&quot;); // Linha em branco
    
    // Clean sandbox directories safely
    safeCleanDirectories();
    
    sleep(CONFIG.timeouts.recovery);
    printSuccess(&quot;LIMPEZA CONCLUÍDA\n&quot;);
    
  } catch (cleanupErr) {
    printError(&quot;Erro durante cleanup: &quot; + cleanupErr.message);
  }
  
  // ==============================================
  // PHASE 1: DEPLOY PRIMARY INSTANCES
  // ==============================================
  printPhase(1, &quot;CRIAÇÃO DAS INSTÂNCIAS PRIMÁRIAS&quot;);
  
  CONFIG.primaryPorts.forEach((port, index) =&gt; {
    try {
      printInfo(&quot;Criando instância primária &quot; + port + &quot;...&quot;);
      
      dba.deploySandboxInstance(port, { 
        password: CONFIG.password,
        sandboxDir: CONFIG.sandboxPath
      });
      
      if (waitForInstanceReady(port)) {
        printSuccess(&quot;Instância primária &quot; + port + &quot; criada e pronta (&quot; + (index + 1) + &quot;/&quot; + CONFIG.primaryPorts.length + &quot;)\n&quot;);
      } else {
        throw new Error(&quot;Instância &quot; + port + &quot; não ficou pronta no tempo esperado&quot;);
      }
      
      sleep(2);
    } catch (e) {
      if (e.message.includes(&quot;already exists&quot;)) {
        printWarning(&quot;Instância &quot; + port + &quot; já existe\n&quot;);
      } else {
        printError(&quot;Erro ao criar instância &quot; + port + &quot;: &quot; + e.message);
        throw e;
      }
    }
  });
  
  // ==============================================
  // PHASE 2: CONFIGURE PRIMARY INSTANCES
  // ==============================================
  printPhase(2, &quot;CONFIGURAÇÃO DAS INSTÂNCIAS PRIMÁRIAS&quot;);
  
  CONFIG.primaryPorts.forEach((port, index) =&gt; {
    try {
      printInfo(&quot;Configurando instância &quot; + port + &quot; para clustering...&quot;);
      
      dba.configureInstance(&quot;root:&quot; + CONFIG.password + &quot;@localhost:&quot; + port, { 
        clusterAdmin: 'root',
        restart: false
      });
      
      printSuccess(&quot;Instância &quot; + port + &quot; configurada (&quot; + (index + 1) + &quot;/&quot; + CONFIG.primaryPorts.length + &quot;)\n&quot;);
      sleep(1);
    } catch (e) {
      printError(&quot;Erro ao configurar instância &quot; + port + &quot;: &quot; + e.message);
      throw e;
    }
  });
  
  // ==============================================
  // PHASE 3: CLUSTER CREATION
  // ==============================================
  printPhase(3, &quot;CRIAÇÃO DO CLUSTER INNODB&quot;);
  
  let cluster;
  try {
    printInfo(&quot;Conectando à instância primária (&quot; + firstPrimaryPort + &quot;)...&quot;);
    shell.connect(&quot;root:&quot; + CONFIG.password + &quot;@localhost:&quot; + firstPrimaryPort);
    printSuccess(&quot;Conectado à instância primária\n&quot;);
    
    try {
      printInfo(&quot;Verificando se cluster '&quot; + CONFIG.clusterName + &quot;' já existe...&quot;);
      cluster = dba.getCluster(CONFIG.clusterName);
      printSuccess(&quot;Cluster '&quot; + CONFIG.clusterName + &quot;' existente carregado\n&quot;);
    } catch {
      printInfo(&quot;Criando novo cluster '&quot; + CONFIG.clusterName + &quot;'...&quot;);
      
      cluster = dba.createCluster(CONFIG.clusterName, {
        multiPrimary: false,
        force: true,
        gtidSetIsComplete: true
      });
      
      printSuccess(&quot;Cluster '&quot; + CONFIG.clusterName + &quot;' criado com sucesso\n&quot;);
      printInfo(&quot;Aguardando estabilização do cluster primário...\n&quot;);
      sleep(CONFIG.timeouts.clusterCreation);
      
      if (checkClusterHealth(cluster)) {
        printSuccess(&quot;Cluster primário está funcionando corretamente\n&quot;);
      } else {
        printWarning(&quot;Cluster primário pode não estar completamente estável\n&quot;);
      }
    }
    
  } catch (e) {
    printError(&quot;Erro na criação/carregamento do cluster: &quot; + e.message);
    throw e;
  }
  
  // ==============================================
  // PHASE 4: ADD SECONDARY INSTANCES TO CLUSTER
  // ==============================================
  printPhase(4, &quot;ADIÇÃO DAS INSTÂNCIAS SECUNDÁRIAS AO CLUSTER&quot;);
  
  const secondaryPorts = CONFIG.primaryPorts.slice(1);
  let addedCount = 0;
  
  secondaryPorts.forEach((port, index) =&gt; {
    let retryCount = 0;
    const maxRetries = 3;
    let added = false;
    
    while (!added &amp;amp;&amp;amp; retryCount &amp;lt; maxRetries) {
      try {
        retryCount++;
        printInfo(&quot;Adicionando instância &quot; + port + &quot; ao cluster (tentativa &quot; + retryCount + &quot;/&quot; + maxRetries + &quot;)...&quot;);
        
        const currentStatus = cluster.status();
        const instanceKey = &quot;127.0.0.1:&quot; + port;
        
        if (currentStatus.defaultReplicaSet.topology&#x5B;instanceKey]) {
          printWarning(&quot;Instância &quot; + port + &quot; já está no cluster\n&quot;);
          added = true;
          addedCount++;
          break;
        }
        
        // ADD INSTANCE TRADICIONAL COM CLONE
        cluster.addInstance(&quot;root:&quot; + CONFIG.password + &quot;@localhost:&quot; + port, {
          recoveryMethod: 'clone'
        });
        
        printSuccess(&quot;Instância &quot; + port + &quot; adicionada ao cluster (&quot; + (index + 1) + &quot;/&quot; + secondaryPorts.length + &quot;)\n&quot;);
        added = true;
        addedCount++;
        
        printInfo(&quot;Aguardando sincronização da instância &quot; + port + &quot;...\n&quot;);
        sleep(CONFIG.timeouts.instanceAdd);
        
        // Verificar status após adicionar
        let instanceOnline = false;
        let checkCount = 0;
        const maxChecks = 10;
        
        while (!instanceOnline &amp;amp;&amp;amp; checkCount &amp;lt; maxChecks) {
          checkCount++;
          const status = cluster.status();
          const instanceStatus = status.defaultReplicaSet.topology&#x5B;instanceKey];
          
          if (instanceStatus &amp;amp;&amp;amp; instanceStatus.status === 'ONLINE') {
            printSuccess(&quot;Instância &quot; + port + &quot; está ONLINE no cluster\n&quot;);
            instanceOnline = true;
          } else if (instanceStatus &amp;amp;&amp;amp; instanceStatus.status === 'RECOVERING') {
            printInfo(&quot;Instância &quot; + port + &quot; está em RECOVERING, aguardando... (&quot; + checkCount + &quot;/&quot; + maxChecks + &quot;)\n&quot;);
            sleep(5);
          } else {
            printWarning(&quot;Instância &quot; + port + &quot; status: &quot; + (instanceStatus ? instanceStatus.status : &quot;DESCONHECIDO&quot;) + &quot;\n&quot;);
            sleep(5);
          }
        }
        
      } catch (e) {
        printError(&quot;Erro ao adicionar instância &quot; + port + &quot; (tentativa &quot; + retryCount + &quot;): &quot; + e.message + &quot;\n&quot;);
        
        if (retryCount &amp;lt; maxRetries) {
          printInfo(&quot;Tentando novamente em 10 segundos...\n&quot;);
          sleep(10);
          
          try {
            printInfo(&quot;Tentando rejoin da instância &quot; + port + &quot;...&quot;);
            cluster.rejoinInstance(&quot;root:&quot; + CONFIG.password + &quot;@localhost:&quot; + port);
            printSuccess(&quot;Instância &quot; + port + &quot; rejoin bem-sucedido\n&quot;);
            added = true;
            addedCount++;
          } catch (rejoinErr) {
            printWarning(&quot;Rejoin falhou: &quot; + rejoinErr.message + &quot;\n&quot;);
          }
        }
      }
    }
    
    if (!added) {
      printError(&quot;Falha ao adicionar instância &quot; + port + &quot; após &quot; + maxRetries + &quot; tentativas&quot;);
      printWarning(&quot;Continuando com as próximas instâncias...\n&quot;);
    }
  });
  
  printInfo(&quot;Total de instâncias secundárias adicionadas: &quot; + addedCount + &quot;/&quot; + secondaryPorts.length);
  printInfo(&quot;Aguardando sincronização completa do cluster...\n&quot;);
  sleep(CONFIG.timeouts.stabilization);
  
  printInfo(&quot;Verificando status do cluster após adição de instâncias...&quot;);
  const clusterStatusAfterAdd = cluster.status();
  const topologyCount = Object.keys(clusterStatusAfterAdd.defaultReplicaSet.topology).length;
  printInfo(&quot;Total de nós no cluster: &quot; + topologyCount + &quot;\n&quot;);
  
  if (topologyCount &amp;lt; 4) {
    printWarning(&quot;ATENÇÃO: Cluster tem apenas &quot; + topologyCount + &quot; nós, esperado 4&quot;);
    printInfo(&quot;Tentando rescan do cluster...\n&quot;);
    cluster.rescan();
  }
  
  // ==============================================
  // PHASE 5: CONFIGURE INSTANCE WEIGHTS
  // ==============================================
  printPhase(5, &quot;CONFIGURAÇÃO DE PESOS DAS INSTÂNCIAS&quot;);
  
  try {
    Object.entries(CONFIG.weights).forEach((&#x5B;port, weight]) =&gt; {
      try {
        cluster.setInstanceOption(&quot;127.0.0.1:&quot; + port, 'memberWeight', weight);
        printSuccess(&quot;Peso &quot; + weight + &quot; configurado para instância &quot; + port);
      } catch (e) {
        printWarning(&quot;Erro ao configurar peso para &quot; + port + &quot;: &quot; + e.message);
      }
    });
    print(&quot;&quot;); // Linha em branco
    printSuccess(&quot;Configuração de pesos concluída\n&quot;);
  } catch (e) {
    printWarning(&quot;Erro geral na configuração de pesos: &quot; + e.message + &quot;\n&quot;);
  }
  
  // ==============================================
  // PHASE 5.5: CREATE REPLICATION USERS ON PRIMARY
  // ==============================================
  printPhase(5.5, &quot;CRIAÇÃO DE USUÁRIOS DE REPLICAÇÃO&quot;);
  
  try {
    printInfo(&quot;Criando usuário de replicação na instância primária (3307)...&quot;);
    const primarySession = mysql.getSession(&quot;root:&quot; + CONFIG.password + &quot;@localhost:&quot; + firstPrimaryPort);
    
    // Criar usuário de replicação com todos os privilégios necessários
    primarySession.runSql(&quot;CREATE USER IF NOT EXISTS '&quot; + CONFIG.replicationUser.username + &quot;'@'%' IDENTIFIED BY '&quot; + CONFIG.replicationUser.password + &quot;'&quot;);
    primarySession.runSql(&quot;GRANT REPLICATION SLAVE ON *.* TO '&quot; + CONFIG.replicationUser.username + &quot;'@'%'&quot;);
    primarySession.runSql(&quot;GRANT BACKUP_ADMIN ON *.* TO '&quot; + CONFIG.replicationUser.username + &quot;'@'%'&quot;);
    primarySession.runSql(&quot;GRANT CLONE_ADMIN ON *.* TO '&quot; + CONFIG.replicationUser.username + &quot;'@'%'&quot;);
    primarySession.runSql(&quot;GRANT SELECT ON *.* TO '&quot; + CONFIG.replicationUser.username + &quot;'@'%'&quot;);
    primarySession.runSql(&quot;FLUSH PRIVILEGES&quot;);
    primarySession.close();
    
    printSuccess(&quot;Usuário de replicação criado com sucesso na instância primária\n&quot;);
    
    // Aguardar propagação para os nós secundários
    printInfo(&quot;Aguardando propagação do usuário para os nós secundários...\n&quot;);
    sleep(5);
    
    // Verificar se o usuário foi propagado para os nós secundários
    const secondaryPortsCheck = CONFIG.primaryPorts.slice(1);
    secondaryPortsCheck.forEach(port =&gt; {
      try {
        const testSession = mysql.getSession(&quot;root:&quot; + CONFIG.password + &quot;@localhost:&quot; + port);
        const result = testSession.runSql(&quot;SELECT user FROM mysql.user WHERE user = '&quot; + CONFIG.replicationUser.username + &quot;'&quot;);
        if (result.fetchOne()) {
          printSuccess(&quot;Usuário de replicação confirmado no nó &quot; + port);
        } else {
          printWarning(&quot;Usuário de replicação não encontrado no nó &quot; + port);
        }
        testSession.close();
      } catch (e) {
        printWarning(&quot;Não foi possível verificar usuário no nó &quot; + port + &quot;: &quot; + e.message);
      }
    });
    print(&quot;&quot;); // Linha em branco
    
  } catch (e) {
    printError(&quot;Erro ao criar usuário de replicação: &quot; + e.message);
    printInfo(&quot;Continuando sem usuário de replicação dedicado...\n&quot;);
  }
  
  // ==============================================
  // PHASE 6: DEPLOY AND CONFIGURE READ REPLICAS
  // ==============================================
  printPhase(6, &quot;CONFIGURAÇÃO DAS RÉPLICAS DE LEITURA&quot;);
  
  // Primeiro, vamos verificar quais nós estão realmente no cluster
  const currentClusterStatus = cluster.status();
  printInfo(&quot;Verificando nós disponíveis no cluster para réplicas...\n&quot;);
  
  for (let index = 0; index &amp;lt; REPLICA_MAPPING.length; index++) {
    const replica = REPLICA_MAPPING&#x5B;index];
    
    try {
      printInfo(&quot;Processando réplica &quot; + replica.port + &quot; para fonte &quot; + replica.source + &quot;...\n&quot;);
      
      // Verificar se a fonte está disponível primeiro
      const sourceKey = &quot;127.0.0.1:&quot; + replica.source;
      const sourceNode = currentClusterStatus.defaultReplicaSet.topology&#x5B;sourceKey];
      
      // Se a fonte não está no cluster, pular esta réplica
      if (!sourceNode) {
        printWarning(&quot;Nó fonte &quot; + replica.source + &quot; não está no cluster, pulando réplica &quot; + replica.port + &quot;\n&quot;);
        continue;
      }
      
      // Se a fonte não está ONLINE, pular esta réplica
      if (sourceNode.status !== 'ONLINE') {
        printWarning(&quot;Nó fonte &quot; + replica.source + &quot; está &quot; + sourceNode.status + &quot;, pulando réplica &quot; + replica.port + &quot;\n&quot;);
        continue;
      }
      
      printInfo(&quot;Nó fonte &quot; + replica.source + &quot; está ONLINE, criando réplica &quot; + replica.port + &quot;...\n&quot;);
      
      // PASSO 1: Criar a instância réplica
      printInfo(&quot;- Criando instância réplica &quot; + replica.port + &quot;...&quot;);
      dba.deploySandboxInstance(replica.port, { 
        password: CONFIG.password,
        sandboxDir: CONFIG.sandboxPath
      });
      
      if (!waitForInstanceReady(replica.port)) {
        throw new Error(&quot;Réplica &quot; + replica.port + &quot; não ficou pronta&quot;);
      }
      
      // PASSO 2: Configurar a instância réplica
      printInfo(&quot;- Configurando instância réplica &quot; + replica.port + &quot;...&quot;);
      dba.configureInstance(&quot;root:&quot; + CONFIG.password + &quot;@localhost:&quot; + replica.port, { 
        clusterAdmin: 'root',
        restart: false
      });
      
      // PASSO 3: Se necessário, desabilitar temporariamente super-read-only no nó fonte
      let needsReadOnlyDisable = false;
      if (replica.source !== firstPrimaryPort) {
        needsReadOnlyDisable = true;
        try {
          printInfo(&quot;- Desabilitando temporariamente super-read-only no nó &quot; + replica.source + &quot;...&quot;);
          const sourceSession = mysql.getSession(&quot;root:&quot; + CONFIG.password + &quot;@localhost:&quot; + replica.source);
          sourceSession.runSql(&quot;SET GLOBAL super_read_only = 0&quot;);
          
          // Criar/verificar usuário de replicação no nó secundário
          sourceSession.runSql(&quot;CREATE USER IF NOT EXISTS '&quot; + CONFIG.replicationUser.username + &quot;'@'localhost' IDENTIFIED BY '&quot; + CONFIG.replicationUser.password + &quot;'&quot;);
          sourceSession.runSql(&quot;GRANT REPLICATION SLAVE ON *.* TO '&quot; + CONFIG.replicationUser.username + &quot;'@'localhost'&quot;);
          sourceSession.runSql(&quot;FLUSH PRIVILEGES&quot;);
          
          sourceSession.close();
          printSuccess(&quot;Super-read-only desabilitado temporariamente no nó &quot; + replica.source);
        } catch (e) {
          printWarning(&quot;Não foi possível desabilitar super-read-only no nó &quot; + replica.source + &quot;: &quot; + e.message);
          needsReadOnlyDisable = false;
        }
      }
      
      sleep(3);
      
      // PASSO 4: Adicionar a réplica ao cluster
      printInfo(&quot;- Adicionando &quot; + replica.port + &quot; como réplica de leitura anexada ao nó &quot; + replica.source + &quot;...&quot;);
      
      try {
        // Adicionar réplica especificamente ao nó fonte
        cluster.addReplicaInstance(&quot;root:&quot; + CONFIG.password + &quot;@localhost:&quot; + replica.port, {
          label: replica.label,
          recoveryMethod: 'clone',
          replicationSources: &#x5B;&quot;127.0.0.1:&quot; + replica.source]
        });
        
        printSuccess(&quot;Réplica &quot; + replica.port + &quot; configurada e anexada ao nó &quot; + replica.source + &quot; (&quot; + (index + 1) + &quot;/&quot; + REPLICA_MAPPING.length + &quot;)\n&quot;);
        sleep(CONFIG.timeouts.recovery);
        
      } catch (replicaErr) {
        printError(&quot;Erro ao adicionar réplica &quot; + replica.port + &quot;: &quot; + replicaErr.message);
        
        // Tentar método alternativo se falhar
        try {
          printInfo(&quot;Tentando método alternativo para adicionar réplica...&quot;);
          cluster.addReplicaInstance(&quot;root:&quot; + CONFIG.password + &quot;@localhost:&quot; + replica.port, {
            label: replica.label,
            recoveryMethod: 'clone'
          });
          printSuccess(&quot;Réplica &quot; + replica.port + &quot; adicionada com método alternativo\n&quot;);
        } catch (altErr) {
          printError(&quot;Método alternativo também falhou: &quot; + altErr.message + &quot;\n&quot;);
        }
      }
      
      // PASSO 5: Reabilitar super-read-only se foi desabilitado
      if (needsReadOnlyDisable) {
        try {
          printInfo(&quot;- Reabilitando super-read-only no nó &quot; + replica.source + &quot;...&quot;);
          const sourceSession = mysql.getSession(&quot;root:&quot; + CONFIG.password + &quot;@localhost:&quot; + replica.source);
          sourceSession.runSql(&quot;SET GLOBAL super_read_only = 1&quot;);
          sourceSession.close();
          printSuccess(&quot;Super-read-only reabilitado no nó &quot; + replica.source + &quot;\n&quot;);
        } catch (e) {
          printWarning(&quot;Não foi possível reabilitar super-read-only no nó &quot; + replica.source + &quot;: &quot; + e.message + &quot;\n&quot;);
        }
      }
      
    } catch (e) {
      printError(&quot;Erro na configuração da réplica &quot; + replica.port + &quot;: &quot; + e.message + &quot;\n&quot;);
      
      try {
        safeKillSandbox(replica.port);
        safeDeleteSandbox(replica.port);
        printInfo(&quot;Limpeza da réplica &quot; + replica.port + &quot; concluída\n&quot;);
      } catch (cleanupErr) {
        printWarning(&quot;Erro na limpeza da réplica &quot; + replica.port + &quot;: &quot; + cleanupErr.message + &quot;\n&quot;);
      }
    }
  }
  
  // PASSO FINAL: Garantir que super-read-only está habilitado em todos os nós secundários
  printInfo(&quot;Verificando configuração final de super-read-only...\n&quot;);
  const secondaryPortsFinal = CONFIG.primaryPorts.slice(1);
  secondaryPortsFinal.forEach(port =&gt; {
    try {
      const session = mysql.getSession(&quot;root:&quot; + CONFIG.password + &quot;@localhost:&quot; + port);
      const result = session.runSql(&quot;SELECT @@super_read_only&quot;);
      const row = result.fetchOne();
      if (row&#x5B;0] === 0) {
        session.runSql(&quot;SET GLOBAL super_read_only = 1&quot;);
        printSuccess(&quot;Super-read-only reabilitado no nó &quot; + port);
      } else {
        printInfo(&quot;Super-read-only já está habilitado no nó &quot; + port);
      }
      session.close();
    } catch (e) {
      printWarning(&quot;Não foi possível verificar super-read-only no nó &quot; + port + &quot;: &quot; + e.message);
    }
  });
  print(&quot;&quot;); // Linha em branco
  
  // ==============================================
  // PHASE 7: FINAL VERIFICATION AND STATUS
  // ==============================================
  printPhase(7, &quot;VERIFICAÇÃO FINAL E STATUS&quot;);
  
  try {
    printInfo(&quot;Aguardando estabilização final...\n&quot;);
    sleep(CONFIG.timeouts.stabilization);
    
    print(&quot;\n📊 STATUS COMPLETO DO CLUSTER:&quot;);
    print(&quot;=&quot; + &quot;=&quot;.repeat(70) + &quot;\n&quot;);
    
    try {
      const clusterStatus = cluster.status({extended: true});
      print(JSON.stringify(clusterStatus, null, 2));
      print(&quot;\n&quot;); // Linha em branco
      
      const defaultReplicaSet = clusterStatus.defaultReplicaSet;
      print(&quot;🎯 ANÁLISE DO STATUS:&quot;);
      print(&quot;• Status Geral: &quot; + defaultReplicaSet.status);
      print(&quot;• Modo: &quot; + (defaultReplicaSet.mode || 'Single-Primary'));
      print(&quot;• SSL Mode: &quot; + (defaultReplicaSet.ssl || 'N/A'));
      print(&quot;\n&quot;); // Linha em branco
      
      const topology = defaultReplicaSet.topology;
      const statusCount = {};
      let onlineNodes = 0;
      let totalReplicas = 0;
      const replicaDetails = &#x5B;];
      
      Object.entries(topology).forEach((&#x5B;key, instance]) =&gt; {
        const status = instance.status;
        statusCount&#x5B;status] = (statusCount&#x5B;status] || 0) + 1;
        
        if (status === 'ONLINE') {
          onlineNodes++;
        }
        
        if (instance.readReplicas) {
          const replicaCount = Object.keys(instance.readReplicas).length;
          totalReplicas += replicaCount;
          if (replicaCount &gt; 0) {
            Object.entries(instance.readReplicas).forEach((&#x5B;replicaKey, replicaInfo]) =&gt; {
              replicaDetails.push(&quot;  • &quot; + key + &quot; → &quot; + replicaKey + &quot; (&quot; + replicaInfo.status + &quot;)&quot;);
            });
          }
        }
      });
      
      print(&quot;📊 RESUMO POR STATUS:&quot;);
      Object.entries(statusCount).forEach((&#x5B;status, count]) =&gt; {
        print(&quot;• &quot; + status + &quot;: &quot; + count + &quot; instância(s)&quot;);
      });
      print(&quot;\n&quot;); // Linha em branco
      
      print(&quot;📈 ESTATÍSTICAS DO CLUSTER:&quot;);
      print(&quot;• Nós ONLINE no cluster: &quot; + onlineNodes);
      print(&quot;• Total de réplicas de leitura: &quot; + totalReplicas);
      print(&quot;• Tolerância a falhas: &quot; + (onlineNodes &gt;= 3 ? &quot;SIM&quot; : &quot;NÃO&quot;));
      print(&quot;\n&quot;); // Linha em branco
      
      if (replicaDetails.length &gt; 0) {
        print(&quot;📚 RÉPLICAS DE LEITURA ANEXADAS:&quot;);
        replicaDetails.forEach(detail =&gt; print(detail));
        print(&quot;\n&quot;); // Linha em branco
      }
      
    } catch (e) {
      printError(&quot;Erro ao obter status do cluster: &quot; + e.message + &quot;\n&quot;);
    }
    
    print(&quot;🔗 TESTE DE CONECTIVIDADE:&quot;);
    print(&quot;=&quot; + &quot;=&quot;.repeat(70) + &quot;\n&quot;);
    CONFIG.primaryPorts.forEach(port =&gt; {
      try {
        const testSession = mysql.getSession(&quot;root:&quot; + CONFIG.password + &quot;@localhost:&quot; + port);
        const result = testSession.runSql(&quot;SELECT @@hostname, @@port, @@server_id&quot;);
        const row = result.fetchOne();
        printSuccess(&quot;Porta &quot; + port + &quot;: Conectividade OK - Server ID: &quot; + row&#x5B;2]);
        testSession.close();
      } catch (e) {
        printError(&quot;Porta &quot; + port + &quot;: Erro de conectividade - &quot; + e.message);
      }
    });
    print(&quot;\n&quot;); // Linha em branco
    
    print(&quot;🔗 TESTE DE CONECTIVIDADE DAS RÉPLICAS:&quot;);
    print(&quot;=&quot; + &quot;=&quot;.repeat(70) + &quot;\n&quot;);
    CONFIG.replicaPorts.forEach(port =&gt; {
      try {
        const testSession = mysql.getSession(&quot;root:&quot; + CONFIG.password + &quot;@localhost:&quot; + port);
        const result = testSession.runSql(&quot;SELECT @@hostname, @@port, @@server_id&quot;);
        const row = result.fetchOne();
        printSuccess(&quot;Réplica &quot; + port + &quot;: Conectividade OK - Server ID: &quot; + row&#x5B;2]);
        testSession.close();
      } catch (e) {
        printWarning(&quot;Réplica &quot; + port + &quot;: Não disponível&quot;);
      }
    });
    print(&quot;\n&quot;); // Linha em branco
    
  } catch (e) {
    printWarning(&quot;Erro na verificação final: &quot; + e.message + &quot;\n&quot;);
  }
  
  // ==============================================
  // FINAL SUMMARY
  // ==============================================
  print(&quot;\n&quot; + &quot;=&quot;.repeat(80));
  print(&quot;🎉 CONFIGURAÇÃO CONCLUÍDA COM SUCESSO! 🎉&quot;);
  print(&quot;=&quot;.repeat(80) + &quot;\n&quot;);
  
  print(&quot;📋 RESUMO DA CONFIGURAÇÃO:&quot;);
  print(&quot;-&quot;.repeat(70));
  print(&quot;• Cluster Name: &quot; + CONFIG.clusterName);
  print(&quot;• Instâncias Primárias: &quot; + CONFIG.primaryPorts.length + &quot; (&quot; + CONFIG.primaryPorts.join(', ') + &quot;)&quot;);
  print(&quot;• Réplicas de Leitura: &quot; + REPLICA_MAPPING.length + &quot; (&quot; + REPLICA_MAPPING.map(r =&gt; r.port).join(', ') + &quot;)&quot;);
  print(&quot;• Total de Instâncias: &quot; + CONFIG.ports.length);
  print(&quot;• Arquitetura: 4-Node Cluster + 4 Read Replicas (1:1)&quot;);
  print(&quot;\n&quot;); // Linha em branco
  
  print(&quot;🔗 MAPEAMENTO DE RÉPLICAS:&quot;);
  print(&quot;-&quot;.repeat(70));
  REPLICA_MAPPING.forEach(replica =&gt; {
    print(&quot;• Nó &quot; + replica.source + &quot; → Réplica &quot; + replica.port + &quot; (&quot; + replica.label + &quot;)&quot;);
  });
  print(&quot;\n&quot;); // Linha em branco
  
  print(&quot;⚖️  PESOS CONFIGURADOS:&quot;);
  print(&quot;-&quot;.repeat(70));
  Object.entries(CONFIG.weights).forEach((&#x5B;port, weight]) =&gt; {
    print(&quot;• Porta &quot; + port + &quot;: Peso &quot; + weight);
  });
  print(&quot;\n&quot;); // Linha em branco
  
  print(&quot;🚀 PRÓXIMOS PASSOS:&quot;);
  print(&quot;-&quot;.repeat(70));
  print(&quot;• Configurar MySQL Router para balanceamento de carga&quot;);
  print(&quot;• Implementar monitoramento e alertas&quot;);
  print(&quot;• Configurar backups automatizados&quot;);
  print(&quot;• Testar failover e recuperação&quot;);
  print(&quot;• Ajustar configurações de performance conforme necessário&quot;);
  print(&quot;\n&quot;); // Linha em branco
  
  print(&quot;💡 COMANDOS ÚTEIS:&quot;);
  print(&quot;-&quot;.repeat(70));
  print(&quot;• Status do cluster: cluster.status({extended: true})&quot;);
  print(&quot;• Conectar ao cluster: shell.connect('root@localhost:3307')&quot;);
  print(&quot;• Obter cluster: dba.getCluster('&quot; + CONFIG.clusterName + &quot;')&quot;);
  print(&quot;• Rescan do cluster: cluster.rescan()&quot;);
  print(&quot;• Verificar réplicas: cluster.listRouters()&quot;);
  print(&quot;\n&quot;); // Linha em branco
  
  print(&quot;📋 COMANDOS PARA MONITORAMENTO (macOS/Linux):&quot;);
  print(&quot;-&quot;.repeat(70));
  print(&quot;# Monitorar log em tempo real:&quot;);
  print(&quot;tail -f /tmp/cluster_setup.log&quot;);
  print(&quot;&quot;);
  print(&quot;# Verificar portas em uso:&quot;);
  print(&quot;lsof -i -P | grep LISTEN | grep :33&quot;);
  print(&quot;&quot;);
  print(&quot;# Verificar processos MySQL:&quot;);
  print(&quot;ps aux | grep mysql&quot;);
  print(&quot;\n&quot;); // Linha em branco
  
  print(&quot;=&quot;.repeat(80));
  printSuccess(&quot;✨ Script executado com sucesso! ✨&quot;);
  print(&quot;=&quot;.repeat(80) + &quot;\n&quot;);

} catch (mainErr) {
  // ==============================================
  // EMERGENCY ERROR HANDLING
  // ==============================================
  print(&quot;\n&quot; + &quot;=&quot;.repeat(80));
  print(&quot;🚨 ERRO CRÍTICO DETECTADO - INICIANDO LIMPEZA DE EMERGÊNCIA 🚨&quot;);
  print(&quot;=&quot;.repeat(80) + &quot;\n&quot;);
  
  printError(&quot;ERRO PRINCIPAL: &quot; + mainErr.message);
  printError(&quot;STACK TRACE: &quot; + (mainErr.stack || 'N/A') + &quot;\n&quot;);
  
  printInfo(&quot;Executando limpeza de emergência...\n&quot;);
  
  try {
    try {
      const emergencyCluster = dba.getCluster();
      if (emergencyCluster) {
        emergencyCluster.dissolve({ force: true });
        printInfo(&quot;Cluster dissolvido durante limpeza de emergência\n&quot;);
      }
    } catch (e) {
      printWarning(&quot;Erro ao dissolver cluster: &quot; + e.message + &quot;\n&quot;);
    }
    
    printInfo(&quot;Removendo todas as instâncias sandbox...&quot;);
    CONFIG.ports.forEach(port =&gt; {
      safeKillSandbox(port);
      safeDeleteSandbox(port);
    });
    print(&quot;\n&quot;); // Linha em branco
    
    safeCleanDirectories();
    
    printSuccess(&quot;Limpeza de emergência concluída\n&quot;);
    
  } catch (emergencyErr) {
    printError(&quot;Erro durante limpeza de emergência: &quot; + emergencyErr.message + &quot;\n&quot;);
  }
  
  print(&quot;💡 SUGESTÕES PARA RESOLUÇÃO:&quot;);
  print(&quot;-&quot;.repeat(70));
  print(&quot;• Verifique se as portas estão disponíveis: lsof -i :330&quot;);
  print(&quot;• Confirme se o MySQL Shell tem permissões adequadas&quot;);
  print(&quot;• Verifique a conectividade de rede&quot;);
  print(&quot;• Analise os logs do MySQL para erros específicos&quot;);
  print(&quot;• Execute o script novamente após corrigir os problemas&quot;);
  print(&quot;• Verifique se há processos MySQL em execução: ps aux | grep mysql&quot;);
  print(&quot;• Limpe manualmente o diretório: rm -rf &quot; + CONFIG.sandboxPath);
  print(&quot;\n&quot;); // Linha em branco
  
  print(&quot;🔧 COMANDOS DE LIMPEZA MANUAL:&quot;);
  print(&quot;-&quot;.repeat(70));
  print(&quot;# Parar e remover todas as instâncias:&quot;);
  print(&quot;for port in 3307 3310 3320 3330 3340 3350 3360 3370; do&quot;);
  print(&quot;  mysqlsh --js -e \&quot;try{dba.killSandboxInstance($port)}catch(e){}\&quot;&quot;);
  print(&quot;  mysqlsh --js -e \&quot;try{dba.deleteSandboxInstance($port)}catch(e){}\&quot;&quot;);
  print(&quot;done&quot;);
  print(&quot;&quot;);
  print(&quot;# Limpar diretório de sandboxes:&quot;);
  print(&quot;rm -rf ~/mysql-sandboxes\n&quot;);
  
  throw mainErr;
}
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
┌&#x5B;acaciolr☮MacBook-Pro-de-Acacio.local]-(~/Library/Mobile Documents/com~apple~CloudDocs/DBA/DBA Scripts/MySQL)
└&gt; mysqlsh --file mysql_innodb_cluster_macOS_mb.js --log-level=8 --log-file=/tmp/cluster.log

================================================================================PHASE 0: LIMPEZA COMPLETA DO AMBIENTE================================================================================
ℹ️  Verificando cluster existente...⚠️  Nenhum cluster ativo encontrado: Iniciando nova configuração
ℹ️  Removendo todas as instâncias sandbox...
Killing MySQL instance...

Instance localhost:3307 successfully killed.

ℹ️  Instância 3307 encerrada
Killing MySQL instance...

Instance localhost:3310 successfully killed.

ℹ️  Instância 3310 encerrada
Killing MySQL instance...

Instance localhost:3320 successfully killed.

ℹ️  Instância 3320 encerrada
Killing MySQL instance...

Instance localhost:3330 successfully killed.

ℹ️  Instância 3330 encerrada
Killing MySQL instance...

Instance localhost:3340 successfully killed.

ℹ️  Instância 3340 encerrada
Killing MySQL instance...

Killing MySQL instance...

Killing MySQL instance...

Deleting MySQL instance...

Instance localhost:3307 successfully deleted.

ℹ️  Instância 3307 removida
Deleting MySQL instance...

Instance localhost:3310 successfully deleted.

ℹ️  Instância 3310 removida
Deleting MySQL instance...

Instance localhost:3320 successfully deleted.

ℹ️  Instância 3320 removida
Deleting MySQL instance...

Instance localhost:3330 successfully deleted.

ℹ️  Instância 3330 removida
Deleting MySQL instance...

Instance localhost:3340 successfully deleted.

ℹ️  Instância 3340 removida
Deleting MySQL instance...

Deleting MySQL instance...

Deleting MySQL instance...
ℹ️  Comando de limpeza preparado: rm -rf /Users/acaciolr/mysql-sandboxes✅ Preparação de limpeza de diretórios concluída⏳ Aguardando 10 segundos...
✅ LIMPEZA CONCLUÍDA

================================================================================PHASE 1: CRIAÇÃO DAS INSTÂNCIAS PRIMÁRIAS================================================================================
ℹ️  Criando instância primária 3307...A new MySQL sandbox instance will be created on this host in
/Users/acaciolr/mysql-sandboxes/3307

Warning: Sandbox instances are only suitable for deploying and
running on your local machine for testing purposes and are not
accessible from external networks.


Deploying new MySQL instance...

Instance localhost:3307 successfully deployed and started.
Use shell.connect('root@localhost:3307') to connect to the instance.

✅ Instância primária 3307 criada e pronta (1/4)
⏳ Aguardando 2 segundos...
ℹ️  Criando instância primária 3310...A new MySQL sandbox instance will be created on this host in
/Users/acaciolr/mysql-sandboxes/3310

Warning: Sandbox instances are only suitable for deploying and
running on your local machine for testing purposes and are not
accessible from external networks.


Deploying new MySQL instance...

Instance localhost:3310 successfully deployed and started.
Use shell.connect('root@localhost:3310') to connect to the instance.

✅ Instância primária 3310 criada e pronta (2/4)
⏳ Aguardando 2 segundos...
ℹ️  Criando instância primária 3320...A new MySQL sandbox instance will be created on this host in
/Users/acaciolr/mysql-sandboxes/3320

Warning: Sandbox instances are only suitable for deploying and
running on your local machine for testing purposes and are not
accessible from external networks.


Deploying new MySQL instance...

Instance localhost:3320 successfully deployed and started.
Use shell.connect('root@localhost:3320') to connect to the instance.

✅ Instância primária 3320 criada e pronta (3/4)
⏳ Aguardando 2 segundos...
ℹ️  Criando instância primária 3330...A new MySQL sandbox instance will be created on this host in
/Users/acaciolr/mysql-sandboxes/3330

Warning: Sandbox instances are only suitable for deploying and
running on your local machine for testing purposes and are not
accessible from external networks.


Deploying new MySQL instance...

Instance localhost:3330 successfully deployed and started.
Use shell.connect('root@localhost:3330') to connect to the instance.

✅ Instância primária 3330 criada e pronta (4/4)
⏳ Aguardando 2 segundos...

================================================================================PHASE 2: CONFIGURAÇÃO DAS INSTÂNCIAS PRIMÁRIAS================================================================================
ℹ️  Configurando instância 3307 para clustering...Configuring local MySQL instance listening at port 3307 for use in an InnoDB Cluster...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.

This instance reports its own address as 127.0.0.1:3307
Assuming full account name 'root'@'%' for root
User 'root'@'%' already exists and will not be created.

applierWorkerThreads will be set to the default value of 4.

The instance '127.0.0.1:3307' is valid for InnoDB Cluster usage.

Successfully enabled parallel appliers.
✅ Instância 3307 configurada (1/4)
⏳ Aguardando 1 segundos...
ℹ️  Configurando instância 3310 para clustering...Configuring local MySQL instance listening at port 3310 for use in an InnoDB Cluster...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.

This instance reports its own address as 127.0.0.1:3310
Assuming full account name 'root'@'%' for root
User 'root'@'%' already exists and will not be created.

applierWorkerThreads will be set to the default value of 4.

The instance '127.0.0.1:3310' is valid for InnoDB Cluster usage.

Successfully enabled parallel appliers.
✅ Instância 3310 configurada (2/4)
⏳ Aguardando 1 segundos...
ℹ️  Configurando instância 3320 para clustering...Configuring local MySQL instance listening at port 3320 for use in an InnoDB Cluster...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.

This instance reports its own address as 127.0.0.1:3320
Assuming full account name 'root'@'%' for root
User 'root'@'%' already exists and will not be created.

applierWorkerThreads will be set to the default value of 4.

The instance '127.0.0.1:3320' is valid for InnoDB Cluster usage.

Successfully enabled parallel appliers.
✅ Instância 3320 configurada (3/4)
⏳ Aguardando 1 segundos...
ℹ️  Configurando instância 3330 para clustering...Configuring local MySQL instance listening at port 3330 for use in an InnoDB Cluster...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.

This instance reports its own address as 127.0.0.1:3330
Assuming full account name 'root'@'%' for root
User 'root'@'%' already exists and will not be created.

applierWorkerThreads will be set to the default value of 4.

The instance '127.0.0.1:3330' is valid for InnoDB Cluster usage.

Successfully enabled parallel appliers.
✅ Instância 3330 configurada (4/4)
⏳ Aguardando 1 segundos...

================================================================================PHASE 3: CRIAÇÃO DO CLUSTER INNODB================================================================================
ℹ️  Conectando à instância primária (3307)...✅ Conectado à instância primária
ℹ️  Verificando se cluster 'my-cluster-db-v5' já existe...ERROR: Command not available on an unmanaged standalone instance.
ℹ️  Criando novo cluster 'my-cluster-db-v5'...A new InnoDB Cluster will be created on instance '127.0.0.1:3307'.

Validating instance configuration at localhost:3307...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.

This instance reports its own address as 127.0.0.1:3307

Instance configuration is suitable.
NOTE: Group Replication will communicate with other members using '127.0.0.1:3307'. Use the localAddress option to override.

* Checking connectivity and SSL configuration...

Creating InnoDB Cluster 'my-cluster-db-v5' on '127.0.0.1:3307'...

Adding Seed Instance...
Cluster successfully created. Use Cluster.addInstance() to add MySQL instances.
At least 3 instances are needed for the cluster to be able to withstand up to
one server failure.

✅ Cluster 'my-cluster-db-v5' criado com sucesso
ℹ️  Aguardando estabilização do cluster primário...
⏳ Aguardando 30 segundos...
ℹ️  Status do cluster: OK_NO_TOLERANCE✅ Cluster primário está funcionando corretamente

================================================================================PHASE 4: ADIÇÃO DAS INSTÂNCIAS SECUNDÁRIAS AO CLUSTER================================================================================
ℹ️  Adicionando instância 3310 ao cluster (tentativa 1/3)...

Clone based recovery selected through the recoveryMethod option

Validating instance configuration at localhost:3310...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.

This instance reports its own address as 127.0.0.1:3310

Instance configuration is suitable.
NOTE: Group Replication will communicate with other members using '127.0.0.1:3310'. Use the localAddress option to override.

* Checking connectivity and SSL configuration...

A new instance will be added to the InnoDB Cluster. Depending on the amount of
data on the cluster this might take from a few seconds to several hours.

Adding instance to the cluster...

Monitoring recovery process of the new cluster member. Press ^C to stop monitoring and let it continue in background.
Clone based state recovery is now in progress.

NOTE: A server restart is expected to happen as part of the clone process. If the
server does not support the RESTART command or does not come back after a
while, you may need to manually start it back.

* Waiting for clone to finish...
NOTE: 127.0.0.1:3310 is being cloned from 127.0.0.1:3307
** Stage DROP DATA: Completed
** Clone Transfer
    FILE COPY  ############################################################  100%  Completed
    PAGE COPY  ############################################################  100%  Completed
    REDO COPY  ############################################################  100%  Completed

NOTE: 127.0.0.1:3310 is shutting down...

* Waiting for server restart... ready
* 127.0.0.1:3310 has restarted, waiting for clone to finish...
** Stage RESTART: Completed
* Clone process has finished: 73.84 MB transferred in about 1 second (~73.84 MB/s)

State recovery already finished for '127.0.0.1:3310'

The instance '127.0.0.1:3310' was successfully added to the cluster.

✅ Instância 3310 adicionada ao cluster (1/3)
ℹ️  Aguardando sincronização da instância 3310...
⏳ Aguardando 20 segundos...
✅ Instância 3310 está ONLINE no cluster
ℹ️  Adicionando instância 3320 ao cluster (tentativa 1/3)...

Clone based recovery selected through the recoveryMethod option

Validating instance configuration at localhost:3320...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.

This instance reports its own address as 127.0.0.1:3320

Instance configuration is suitable.
NOTE: Group Replication will communicate with other members using '127.0.0.1:3320'. Use the localAddress option to override.

* Checking connectivity and SSL configuration...

A new instance will be added to the InnoDB Cluster. Depending on the amount of
data on the cluster this might take from a few seconds to several hours.

Adding instance to the cluster...

Monitoring recovery process of the new cluster member. Press ^C to stop monitoring and let it continue in background.
Clone based state recovery is now in progress.

NOTE: A server restart is expected to happen as part of the clone process. If the
server does not support the RESTART command or does not come back after a
while, you may need to manually start it back.

* Waiting for clone to finish...
NOTE: 127.0.0.1:3320 is being cloned from 127.0.0.1:3307
** Stage DROP DATA: Completed
** Clone Transfer
    FILE COPY  ############################################################  100%  Completed
    PAGE COPY  ############################################################  100%  Completed
    REDO COPY  ############################################################  100%  Completed

NOTE: 127.0.0.1:3320 is shutting down...

* Waiting for server restart... ready
* 127.0.0.1:3320 has restarted, waiting for clone to finish...
** Stage RESTART: Completed
* Clone process has finished: 73.82 MB transferred in about 1 second (~73.82 MB/s)

State recovery already finished for '127.0.0.1:3320'

The instance '127.0.0.1:3320' was successfully added to the cluster.

✅ Instância 3320 adicionada ao cluster (2/3)
ℹ️  Aguardando sincronização da instância 3320...
⏳ Aguardando 20 segundos...
✅ Instância 3320 está ONLINE no cluster
ℹ️  Adicionando instância 3330 ao cluster (tentativa 1/3)...

Clone based recovery selected through the recoveryMethod option

Validating instance configuration at localhost:3330...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.

This instance reports its own address as 127.0.0.1:3330

Instance configuration is suitable.
NOTE: Group Replication will communicate with other members using '127.0.0.1:3330'. Use the localAddress option to override.

* Checking connectivity and SSL configuration...

A new instance will be added to the InnoDB Cluster. Depending on the amount of
data on the cluster this might take from a few seconds to several hours.

Adding instance to the cluster...

Monitoring recovery process of the new cluster member. Press ^C to stop monitoring and let it continue in background.
Clone based state recovery is now in progress.

NOTE: A server restart is expected to happen as part of the clone process. If the
server does not support the RESTART command or does not come back after a
while, you may need to manually start it back.

* Waiting for clone to finish...
NOTE: 127.0.0.1:3330 is being cloned from 127.0.0.1:3307
** Stage DROP DATA: Completed
** Clone Transfer
    FILE COPY  ############################################################  100%  Completed
    PAGE COPY  ############################################################  100%  Completed
    REDO COPY  ############################################################  100%  Completed

NOTE: 127.0.0.1:3330 is shutting down...

* Waiting for server restart... ready
* 127.0.0.1:3330 has restarted, waiting for clone to finish...
** Stage RESTART: Completed
* Clone process has finished: 73.84 MB transferred in about 1 second (~73.84 MB/s)

State recovery already finished for '127.0.0.1:3330'

The instance '127.0.0.1:3330' was successfully added to the cluster.

✅ Instância 3330 adicionada ao cluster (3/3)
ℹ️  Aguardando sincronização da instância 3330...
⏳ Aguardando 20 segundos...
✅ Instância 3330 está ONLINE no cluster
ℹ️  Total de instâncias secundárias adicionadas: 3/3ℹ️  Aguardando sincronização completa do cluster...
⏳ Aguardando 15 segundos...
ℹ️  Verificando status do cluster após adição de instâncias...ℹ️  Total de nós no cluster: 4

================================================================================PHASE 5: CONFIGURAÇÃO DE PESOS DAS INSTÂNCIAS================================================================================
Setting the value of 'memberWeight' to '100' in the instance: '127.0.0.1:3307' ...

Successfully set the value of 'memberWeight' to '100' in the cluster member: '127.0.0.1:3307'.
✅ Peso 100 configurado para instância 3307Setting the value of 'memberWeight' to '60' in the instance: '127.0.0.1:3310' ...

Successfully set the value of 'memberWeight' to '60' in the cluster member: '127.0.0.1:3310'.
✅ Peso 60 configurado para instância 3310Setting the value of 'memberWeight' to '40' in the instance: '127.0.0.1:3320' ...

Successfully set the value of 'memberWeight' to '40' in the cluster member: '127.0.0.1:3320'.
✅ Peso 40 configurado para instância 3320Setting the value of 'memberWeight' to '20' in the instance: '127.0.0.1:3330' ...

Successfully set the value of 'memberWeight' to '20' in the cluster member: '127.0.0.1:3330'.
✅ Peso 20 configurado para instância 3330✅ Configuração de pesos concluída

================================================================================PHASE 5.5: CRIAÇÃO DE USUÁRIOS DE REPLICAÇÃO================================================================================
ℹ️  Criando usuário de replicação na instância primária (3307)...✅ Usuário de replicação criado com sucesso na instância primária
ℹ️  Aguardando propagação do usuário para os nós secundários...
⏳ Aguardando 5 segundos...
✅ Usuário de replicação confirmado no nó 3310✅ Usuário de replicação confirmado no nó 3320✅ Usuário de replicação confirmado no nó 3330
================================================================================PHASE 6: CONFIGURAÇÃO DAS RÉPLICAS DE LEITURA================================================================================
ℹ️  Verificando nós disponíveis no cluster para réplicas...
ℹ️  Processando réplica 3340 para fonte 3307...
ℹ️  Nó fonte 3307 está ONLINE, criando réplica 3340...
ℹ️  - Criando instância réplica 3340...A new MySQL sandbox instance will be created on this host in
/Users/acaciolr/mysql-sandboxes/3340

Warning: Sandbox instances are only suitable for deploying and
running on your local machine for testing purposes and are not
accessible from external networks.


Deploying new MySQL instance...

Instance localhost:3340 successfully deployed and started.
Use shell.connect('root@localhost:3340') to connect to the instance.

ℹ️  - Configurando instância réplica 3340...Configuring local MySQL instance listening at port 3340 for use in an InnoDB Cluster...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.

This instance reports its own address as 127.0.0.1:3340
Assuming full account name 'root'@'%' for root
User 'root'@'%' already exists and will not be created.

applierWorkerThreads will be set to the default value of 4.

The instance '127.0.0.1:3340' is valid for InnoDB Cluster usage.

Successfully enabled parallel appliers.
⏳ Aguardando 3 segundos...
ℹ️  - Adicionando 3340 como réplica de leitura anexada ao nó 3307...Setting up '127.0.0.1:3340' as a Read Replica of Cluster 'my-cluster-db-v5'.

Validating instance configuration at localhost:3340...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.

This instance reports its own address as 127.0.0.1:3340

Instance configuration is suitable.
* Checking transaction state of the instance...


Clone based recovery selected through the recoveryMethod option

* Checking connectivity and SSL configuration...

Monitoring Clone based state recovery of the new member. Press ^C to abort the operation.
Clone based state recovery is now in progress.

NOTE: A server restart is expected to happen as part of the clone process. If the
server does not support the RESTART command or does not come back after a
while, you may need to manually start it back.

* Waiting for clone to finish...
NOTE: 127.0.0.1:3340 is being cloned from 127.0.0.1:3307
** Stage DROP DATA: Completed
** Clone Transfer
    FILE COPY  ############################################################  100%  Completed
    PAGE COPY  ############################################################  100%  Completed
    REDO COPY  ############################################################  100%  Completed
* Clone process has finished: 73.84 MB transferred in about 1 second (~73.84 MB/s)

* Configuring Read-Replica managed replication channel...
** Changing replication source of 127.0.0.1:3340 to 127.0.0.1:3307

* Waiting for Read-Replica '127.0.0.1:3340' to synchronize with Cluster...
** Transactions replicated  ############################################################  100%



'127.0.0.1:3340' successfully added as a Read-Replica of Cluster 'my-cluster-db-v5'.

✅ Réplica 3340 configurada e anexada ao nó 3307 (1/4)
⏳ Aguardando 10 segundos...
ℹ️  Processando réplica 3350 para fonte 3310...
ℹ️  Nó fonte 3310 está ONLINE, criando réplica 3350...
ℹ️  - Criando instância réplica 3350...A new MySQL sandbox instance will be created on this host in
/Users/acaciolr/mysql-sandboxes/3350

Warning: Sandbox instances are only suitable for deploying and
running on your local machine for testing purposes and are not
accessible from external networks.


Deploying new MySQL instance...

Instance localhost:3350 successfully deployed and started.
Use shell.connect('root@localhost:3350') to connect to the instance.

ℹ️  - Configurando instância réplica 3350...Configuring local MySQL instance listening at port 3350 for use in an InnoDB Cluster...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.

This instance reports its own address as 127.0.0.1:3350
Assuming full account name 'root'@'%' for root
User 'root'@'%' already exists and will not be created.

applierWorkerThreads will be set to the default value of 4.

The instance '127.0.0.1:3350' is valid for InnoDB Cluster usage.

Successfully enabled parallel appliers.
ℹ️  - Desabilitando temporariamente super-read-only no nó 3310...✅ Super-read-only desabilitado temporariamente no nó 3310⏳ Aguardando 3 segundos...
ℹ️  - Adicionando 3350 como réplica de leitura anexada ao nó 3310...Setting up '127.0.0.1:3350' as a Read Replica of Cluster 'my-cluster-db-v5'.

Validating instance configuration at localhost:3350...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.

This instance reports its own address as 127.0.0.1:3350

Instance configuration is suitable.
* Checking transaction state of the instance...
NOTE: A GTID set check of the MySQL instance at '127.0.0.1:3350' determined that it is missing transactions that were purged from all cluster members.
NOTE: The target instance '127.0.0.1:3350' has not been pre-provisioned (GTID set is empty). The Shell is unable to determine whether the instance has pre-existing data that would be overwritten with clone based recovery.

Clone based recovery selected through the recoveryMethod option

* Checking connectivity and SSL configuration...

* Waiting for the donor to synchronize with PRIMARY...
** Transactions replicated  ############################################################  100%



Monitoring Clone based state recovery of the new member. Press ^C to abort the operation.
Clone based state recovery is now in progress.

NOTE: A server restart is expected to happen as part of the clone process. If the
server does not support the RESTART command or does not come back after a
while, you may need to manually start it back.

* Waiting for clone to finish...
NOTE: 127.0.0.1:3350 is being cloned from 127.0.0.1:3310
** Stage DROP DATA: Completed
** Clone Transfer
    FILE COPY  ############################################################  100%  Completed
    PAGE COPY  ############################################################  100%  Completed
    REDO COPY  ############################################################  100%  Completed
* Clone process has finished: 74.89 MB transferred in about 1 second (~74.89 MB/s)

* Configuring Read-Replica managed replication channel...
** Changing replication source of 127.0.0.1:3350 to 127.0.0.1:3310

* Waiting for Read-Replica '127.0.0.1:3350' to synchronize with Cluster...
** Transactions replicated  ############################################################  100%



'127.0.0.1:3350' successfully added as a Read-Replica of Cluster 'my-cluster-db-v5'.

✅ Réplica 3350 configurada e anexada ao nó 3310 (2/4)
⏳ Aguardando 10 segundos...
ℹ️  - Reabilitando super-read-only no nó 3310...✅ Super-read-only reabilitado no nó 3310
ℹ️  Processando réplica 3360 para fonte 3320...
ℹ️  Nó fonte 3320 está ONLINE, criando réplica 3360...
ℹ️  - Criando instância réplica 3360...A new MySQL sandbox instance will be created on this host in
/Users/acaciolr/mysql-sandboxes/3360

Warning: Sandbox instances are only suitable for deploying and
running on your local machine for testing purposes and are not
accessible from external networks.


Deploying new MySQL instance...

Instance localhost:3360 successfully deployed and started.
Use shell.connect('root@localhost:3360') to connect to the instance.

ℹ️  - Configurando instância réplica 3360...Configuring local MySQL instance listening at port 3360 for use in an InnoDB Cluster...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.

This instance reports its own address as 127.0.0.1:3360
Assuming full account name 'root'@'%' for root
User 'root'@'%' already exists and will not be created.

applierWorkerThreads will be set to the default value of 4.

The instance '127.0.0.1:3360' is valid for InnoDB Cluster usage.

Successfully enabled parallel appliers.
ℹ️  - Desabilitando temporariamente super-read-only no nó 3320...✅ Super-read-only desabilitado temporariamente no nó 3320⏳ Aguardando 3 segundos...
ℹ️  - Adicionando 3360 como réplica de leitura anexada ao nó 3320...Setting up '127.0.0.1:3360' as a Read Replica of Cluster 'my-cluster-db-v5'.

Validating instance configuration at localhost:3360...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.

This instance reports its own address as 127.0.0.1:3360

Instance configuration is suitable.
* Checking transaction state of the instance...
NOTE: A GTID set check of the MySQL instance at '127.0.0.1:3360' determined that it is missing transactions that were purged from all cluster members.
NOTE: The target instance '127.0.0.1:3360' has not been pre-provisioned (GTID set is empty). The Shell is unable to determine whether the instance has pre-existing data that would be overwritten with clone based recovery.

Clone based recovery selected through the recoveryMethod option

* Checking connectivity and SSL configuration...

* Waiting for the donor to synchronize with PRIMARY...
** Transactions replicated  ############################################################  100%



Monitoring Clone based state recovery of the new member. Press ^C to abort the operation.
Clone based state recovery is now in progress.

NOTE: A server restart is expected to happen as part of the clone process. If the
server does not support the RESTART command or does not come back after a
while, you may need to manually start it back.

* Waiting for clone to finish...
NOTE: 127.0.0.1:3360 is being cloned from 127.0.0.1:3320
** Stage DROP DATA: Completed
** Clone Transfer
    FILE COPY  ############################################################  100%  Completed
    PAGE COPY  ############################################################  100%  Completed
    REDO COPY  ############################################################  100%  Completed
* Clone process has finished: 74.87 MB transferred in about 1 second (~74.87 MB/s)

* Configuring Read-Replica managed replication channel...
** Changing replication source of 127.0.0.1:3360 to 127.0.0.1:3320

* Waiting for Read-Replica '127.0.0.1:3360' to synchronize with Cluster...
** Transactions replicated  ############################################################  100%



'127.0.0.1:3360' successfully added as a Read-Replica of Cluster 'my-cluster-db-v5'.

✅ Réplica 3360 configurada e anexada ao nó 3320 (3/4)
⏳ Aguardando 10 segundos...
ℹ️  - Reabilitando super-read-only no nó 3320...✅ Super-read-only reabilitado no nó 3320
ℹ️  Processando réplica 3370 para fonte 3330...
ℹ️  Nó fonte 3330 está ONLINE, criando réplica 3370...
ℹ️  - Criando instância réplica 3370...A new MySQL sandbox instance will be created on this host in
/Users/acaciolr/mysql-sandboxes/3370

Warning: Sandbox instances are only suitable for deploying and
running on your local machine for testing purposes and are not
accessible from external networks.


Deploying new MySQL instance...

Instance localhost:3370 successfully deployed and started.
Use shell.connect('root@localhost:3370') to connect to the instance.

ℹ️  - Configurando instância réplica 3370...Configuring local MySQL instance listening at port 3370 for use in an InnoDB Cluster...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.

This instance reports its own address as 127.0.0.1:3370
Assuming full account name 'root'@'%' for root
User 'root'@'%' already exists and will not be created.

applierWorkerThreads will be set to the default value of 4.

The instance '127.0.0.1:3370' is valid for InnoDB Cluster usage.

Successfully enabled parallel appliers.
ℹ️  - Desabilitando temporariamente super-read-only no nó 3330...✅ Super-read-only desabilitado temporariamente no nó 3330⏳ Aguardando 3 segundos...
ℹ️  - Adicionando 3370 como réplica de leitura anexada ao nó 3330...Setting up '127.0.0.1:3370' as a Read Replica of Cluster 'my-cluster-db-v5'.

Validating instance configuration at localhost:3370...
NOTE: Instance detected as a sandbox.
Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.

This instance reports its own address as 127.0.0.1:3370

Instance configuration is suitable.
* Checking transaction state of the instance...
NOTE: A GTID set check of the MySQL instance at '127.0.0.1:3370' determined that it is missing transactions that were purged from all cluster members.
NOTE: The target instance '127.0.0.1:3370' has not been pre-provisioned (GTID set is empty). The Shell is unable to determine whether the instance has pre-existing data that would be overwritten with clone based recovery.

Clone based recovery selected through the recoveryMethod option

* Checking connectivity and SSL configuration...

* Waiting for the donor to synchronize with PRIMARY...
** Transactions replicated  ############################################################  100%



Monitoring Clone based state recovery of the new member. Press ^C to abort the operation.
Clone based state recovery is now in progress.

NOTE: A server restart is expected to happen as part of the clone process. If the
server does not support the RESTART command or does not come back after a
while, you may need to manually start it back.

* Waiting for clone to finish...
NOTE: 127.0.0.1:3370 is being cloned from 127.0.0.1:3330
** Stage DROP DATA: Completed
** Clone Transfer
    FILE COPY  ############################################################  100%  Completed
    PAGE COPY  ############################################################  100%  Completed
    REDO COPY  ############################################################  100%  Completed
* Clone process has finished: 74.89 MB transferred in about 1 second (~74.89 MB/s)

* Configuring Read-Replica managed replication channel...
** Changing replication source of 127.0.0.1:3370 to 127.0.0.1:3330

* Waiting for Read-Replica '127.0.0.1:3370' to synchronize with Cluster...
** Transactions replicated  ############################################################  100%



'127.0.0.1:3370' successfully added as a Read-Replica of Cluster 'my-cluster-db-v5'.

✅ Réplica 3370 configurada e anexada ao nó 3330 (4/4)
⏳ Aguardando 10 segundos...
ℹ️  - Reabilitando super-read-only no nó 3330...✅ Super-read-only reabilitado no nó 3330
ℹ️  Verificando configuração final de super-read-only...
ℹ️  Super-read-only já está habilitado no nó 3310ℹ️  Super-read-only já está habilitado no nó 3320ℹ️  Super-read-only já está habilitado no nó 3330
================================================================================PHASE 7: VERIFICAÇÃO FINAL E STATUS================================================================================
ℹ️  Aguardando estabilização final...
⏳ Aguardando 15 segundos...

📊 STATUS COMPLETO DO CLUSTER:=======================================================================
{
  &quot;clusterName&quot;: &quot;my-cluster-db-v5&quot;,
  &quot;defaultReplicaSet&quot;: {
    &quot;GRProtocolVersion&quot;: &quot;8.0.27&quot;,
    &quot;communicationStack&quot;: &quot;MYSQL&quot;,
    &quot;groupName&quot;: &quot;650a7be8-9275-11f0-8693-735b6f1b3cd9&quot;,
    &quot;groupViewChangeUuid&quot;: &quot;AUTOMATIC&quot;,
    &quot;groupViewId&quot;: &quot;17579693355065660:10&quot;,
    &quot;name&quot;: &quot;default&quot;,
    &quot;paxosSingleLeader&quot;: &quot;OFF&quot;,
    &quot;primary&quot;: &quot;127.0.0.1:3307&quot;,
    &quot;ssl&quot;: &quot;REQUIRED&quot;,
    &quot;status&quot;: &quot;OK&quot;,
    &quot;statusText&quot;: &quot;Cluster is ONLINE and can tolerate up to ONE failure.&quot;,
    &quot;topology&quot;: {
      &quot;127.0.0.1:3307&quot;: {
        &quot;address&quot;: &quot;127.0.0.1:3307&quot;,
        &quot;applierWorkerThreads&quot;: 4,
        &quot;fenceSysVars&quot;: &#x5B;],
        &quot;memberId&quot;: &quot;499c9602-9275-11f0-b1ea-d038aaac61de&quot;,
        &quot;memberRole&quot;: &quot;PRIMARY&quot;,
        &quot;memberState&quot;: &quot;ONLINE&quot;,
        &quot;mode&quot;: &quot;R/W&quot;,
        &quot;readReplicas&quot;: {
          &quot;Replica_Primary_3307&quot;: {
            &quot;address&quot;: &quot;127.0.0.1:3340&quot;,
            &quot;applierStatus&quot;: &quot;APPLIED_ALL&quot;,
            &quot;applierThreadState&quot;: &quot;Waiting for an event from Coordinator&quot;,
            &quot;applierWorkerThreads&quot;: 4,
            &quot;receiverStatus&quot;: &quot;ON&quot;,
            &quot;receiverThreadState&quot;: &quot;Waiting for source to send event&quot;,
            &quot;replicationLag&quot;: &quot;applier_queue_applied&quot;,
            &quot;replicationSources&quot;: &#x5B;
              &quot;127.0.0.1:3307&quot;
            ],
            &quot;replicationSsl&quot;: &quot;TLS_AES_128_GCM_SHA256 TLSv1.3&quot;,
            &quot;role&quot;: &quot;READ_REPLICA&quot;,
            &quot;status&quot;: &quot;ONLINE&quot;,
            &quot;version&quot;: &quot;8.4.3&quot;
          }
        },
        &quot;replicationLag&quot;: &quot;applier_queue_applied&quot;,
        &quot;role&quot;: &quot;HA&quot;,
        &quot;status&quot;: &quot;ONLINE&quot;,
        &quot;version&quot;: &quot;8.4.3&quot;
      },
      &quot;127.0.0.1:3310&quot;: {
        &quot;address&quot;: &quot;127.0.0.1:3310&quot;,
        &quot;applierWorkerThreads&quot;: 4,
        &quot;fenceSysVars&quot;: &#x5B;
          &quot;read_only&quot;,
          &quot;super_read_only&quot;
        ],
        &quot;memberId&quot;: &quot;51138f80-9275-11f0-b352-d6511470f888&quot;,
        &quot;memberRole&quot;: &quot;SECONDARY&quot;,
        &quot;memberState&quot;: &quot;ONLINE&quot;,
        &quot;mode&quot;: &quot;R/O&quot;,
        &quot;readReplicas&quot;: {
          &quot;Replica_Secondary_3310&quot;: {
            &quot;address&quot;: &quot;127.0.0.1:3350&quot;,
            &quot;applierStatus&quot;: &quot;APPLIED_ALL&quot;,
            &quot;applierThreadState&quot;: &quot;Waiting for an event from Coordinator&quot;,
            &quot;applierWorkerThreads&quot;: 4,
            &quot;receiverStatus&quot;: &quot;ON&quot;,
            &quot;receiverThreadState&quot;: &quot;Waiting for source to send event&quot;,
            &quot;replicationLag&quot;: &quot;applier_queue_applied&quot;,
            &quot;replicationSources&quot;: &#x5B;
              &quot;127.0.0.1:3310&quot;
            ],
            &quot;role&quot;: &quot;READ_REPLICA&quot;,
            &quot;status&quot;: &quot;ONLINE&quot;,
            &quot;version&quot;: &quot;8.4.3&quot;
          }
        },
        &quot;replicationLag&quot;: &quot;applier_queue_applied&quot;,
        &quot;role&quot;: &quot;HA&quot;,
        &quot;status&quot;: &quot;ONLINE&quot;,
        &quot;version&quot;: &quot;8.4.3&quot;
      },
      &quot;127.0.0.1:3320&quot;: {
        &quot;address&quot;: &quot;127.0.0.1:3320&quot;,
        &quot;applierWorkerThreads&quot;: 4,
        &quot;fenceSysVars&quot;: &#x5B;
          &quot;read_only&quot;,
          &quot;super_read_only&quot;
        ],
        &quot;memberId&quot;: &quot;5749c8e2-9275-11f0-a8ca-524150cc11ed&quot;,
        &quot;memberRole&quot;: &quot;SECONDARY&quot;,
        &quot;memberState&quot;: &quot;ONLINE&quot;,
        &quot;mode&quot;: &quot;R/O&quot;,
        &quot;readReplicas&quot;: {
          &quot;Replica_Tertiary_3320&quot;: {
            &quot;address&quot;: &quot;127.0.0.1:3360&quot;,
            &quot;applierStatus&quot;: &quot;APPLIED_ALL&quot;,
            &quot;applierThreadState&quot;: &quot;Waiting for an event from Coordinator&quot;,
            &quot;applierWorkerThreads&quot;: 4,
            &quot;receiverStatus&quot;: &quot;ON&quot;,
            &quot;receiverThreadState&quot;: &quot;Waiting for source to send event&quot;,
            &quot;replicationLag&quot;: &quot;applier_queue_applied&quot;,
            &quot;replicationSources&quot;: &#x5B;
              &quot;127.0.0.1:3320&quot;
            ],
            &quot;role&quot;: &quot;READ_REPLICA&quot;,
            &quot;status&quot;: &quot;ONLINE&quot;,
            &quot;version&quot;: &quot;8.4.3&quot;
          }
        },
        &quot;replicationLag&quot;: &quot;applier_queue_applied&quot;,
        &quot;role&quot;: &quot;HA&quot;,
        &quot;status&quot;: &quot;ONLINE&quot;,
        &quot;version&quot;: &quot;8.4.3&quot;
      },
      &quot;127.0.0.1:3330&quot;: {
        &quot;address&quot;: &quot;127.0.0.1:3330&quot;,
        &quot;applierWorkerThreads&quot;: 4,
        &quot;fenceSysVars&quot;: &#x5B;
          &quot;read_only&quot;,
          &quot;super_read_only&quot;
        ],
        &quot;memberId&quot;: &quot;5daecdfe-9275-11f0-8a3f-de7098aa8dc1&quot;,
        &quot;memberRole&quot;: &quot;SECONDARY&quot;,
        &quot;memberState&quot;: &quot;ONLINE&quot;,
        &quot;mode&quot;: &quot;R/O&quot;,
        &quot;readReplicas&quot;: {
          &quot;Replica_Quaternary_3330&quot;: {
            &quot;address&quot;: &quot;127.0.0.1:3370&quot;,
            &quot;applierStatus&quot;: &quot;APPLIED_ALL&quot;,
            &quot;applierThreadState&quot;: &quot;Waiting for an event from Coordinator&quot;,
            &quot;applierWorkerThreads&quot;: 4,
            &quot;receiverStatus&quot;: &quot;ON&quot;,
            &quot;receiverThreadState&quot;: &quot;Waiting for source to send event&quot;,
            &quot;replicationLag&quot;: &quot;applier_queue_applied&quot;,
            &quot;replicationSources&quot;: &#x5B;
              &quot;127.0.0.1:3330&quot;
            ],
            &quot;role&quot;: &quot;READ_REPLICA&quot;,
            &quot;status&quot;: &quot;ONLINE&quot;,
            &quot;version&quot;: &quot;8.4.3&quot;
          }
        },
        &quot;replicationLag&quot;: &quot;applier_queue_applied&quot;,
        &quot;role&quot;: &quot;HA&quot;,
        &quot;status&quot;: &quot;ONLINE&quot;,
        &quot;version&quot;: &quot;8.4.3&quot;
      }
    },
    &quot;topologyMode&quot;: &quot;Single-Primary&quot;
  },
  &quot;groupInformationSourceMember&quot;: &quot;127.0.0.1:3307&quot;,
  &quot;metadataVersion&quot;: &quot;2.3.0&quot;
}
🎯 ANÁLISE DO STATUS:• Status Geral: OK• Modo: Single-Primary• SSL Mode: REQUIRED
📊 RESUMO POR STATUS:• ONLINE: 4 instância(s)
📈 ESTATÍSTICAS DO CLUSTER:• Nós ONLINE no cluster: 4• Total de réplicas de leitura: 4• Tolerância a falhas: SIM
📚 RÉPLICAS DE LEITURA ANEXADAS:  • 127.0.0.1:3307 → Replica_Primary_3307 (ONLINE)  • 127.0.0.1:3310 → Replica_Secondary_3310 (ONLINE)  • 127.0.0.1:3320 → Replica_Tertiary_3320 (ONLINE)  • 127.0.0.1:3330 → Replica_Quaternary_3330 (ONLINE)
🔗 TESTE DE CONECTIVIDADE:=======================================================================
✅ Porta 3307: Conectividade OK - Server ID: 4288433930✅ Porta 3310: Conectividade OK - Server ID: 646259890✅ Porta 3320: Conectividade OK - Server ID: 3535963276✅ Porta 3330: Conectividade OK - Server ID: 1379475883
🔗 TESTE DE CONECTIVIDADE DAS RÉPLICAS:=======================================================================
✅ Réplica 3340: Conectividade OK - Server ID: 1064444721✅ Réplica 3350: Conectividade OK - Server ID: 2777852472✅ Réplica 3360: Conectividade OK - Server ID: 304947572✅ Réplica 3370: Conectividade OK - Server ID: 2936623678

================================================================================🎉 CONFIGURAÇÃO CONCLUÍDA COM SUCESSO! 🎉================================================================================
📋 RESUMO DA CONFIGURAÇÃO:----------------------------------------------------------------------• Cluster Name: my-cluster-db-v5• Instâncias Primárias: 4 (3307, 3310, 3320, 3330)• Réplicas de Leitura: 4 (3340, 3350, 3360, 3370)• Total de Instâncias: 8• Arquitetura: 4-Node Cluster + 4 Read Replicas (1:1)
🔗 MAPEAMENTO DE RÉPLICAS:----------------------------------------------------------------------• Nó 3307 → Réplica 3340 (Replica_Primary_3307)• Nó 3310 → Réplica 3350 (Replica_Secondary_3310)• Nó 3320 → Réplica 3360 (Replica_Tertiary_3320)• Nó 3330 → Réplica 3370 (Replica_Quaternary_3330)
⚖️  PESOS CONFIGURADOS:----------------------------------------------------------------------• Porta 3307: Peso 100• Porta 3310: Peso 60• Porta 3320: Peso 40• Porta 3330: Peso 20
🚀 PRÓXIMOS PASSOS:----------------------------------------------------------------------• Configurar MySQL Router para balanceamento de carga• Implementar monitoramento e alertas• Configurar backups automatizados• Testar failover e recuperação• Ajustar configurações de performance conforme necessário
💡 COMANDOS ÚTEIS:----------------------------------------------------------------------• Status do cluster: cluster.status({extended: true})• Conectar ao cluster: shell.connect('root@localhost:3307')• Obter cluster: dba.getCluster('my-cluster-db-v5')• Rescan do cluster: cluster.rescan()• Verificar réplicas: cluster.listRouters()
📋 COMANDOS PARA MONITORAMENTO (macOS/Linux):----------------------------------------------------------------------# Monitorar log em tempo real:tail -f /tmp/cluster_setup.log# Verificar portas em uso:lsof -i -P | grep LISTEN | grep :33# Verificar processos MySQL:ps aux | grep mysql
================================================================================✅ ✨ Script executado com sucesso! ✨================================================================================
┌&#x5B;acaciolr☮MacBook-Pro-de-Acacio.local]-(~/Library/Mobile Documents/com~apple~CloudDocs/DBA/DBA Scripts/MySQL)
</pre></div>


<p>Eu resolvi compartilhar a ideia pra não deixa no /dev/null, mas existem melhorias a serem aplicadas, conforme for ajustando eu vou atualizando o script aqui, caso tenham melhorias ou sugestões podem publicar nos comentários ou me chamar no nas redes que podemos trocar ideias e bater figurinhas hahaha. </p>



<p>Abraço.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Oracle DBMS_SCHEDULER vs DBMS_JOB: pacote único para gerenciar, pausar e monitorar jobs</title>
		<link>https://furushima.com.br/blog/oracle-dbms_scheduler-vs-dbms_job-pacote-unico-para-gerenciar-pausar-e-monitorar-jobs/</link>
		
		<dc:creator><![CDATA[Carlos Furushima]]></dc:creator>
		<pubDate>Wed, 10 Sep 2025 22:11:24 +0000</pubDate>
				<category><![CDATA[Banco De Dados]]></category>
		<category><![CDATA[Oracle]]></category>
		<guid isPermaLink="false">https://furushima.com.br/?p=2855</guid>

					<description><![CDATA[Introdução Em muitos ambientes Oracle, convivem dois mecanismos de agendamento: o DBMS_SCHEDULER (moderno) e o DBMS_JOB (legado). Cada um possui comandos, dicionários e semânticas próprios — &#8220;enabled" de um lado, &#8220;broken&#8221; do outro; DBA_SCHEDULER_* aqui, DBA_JOBS* ali; STOP_JOB vs. &#8220;matar sessão&#8221; etc.O resultado, no dia a dia, é fricção operacional: consultas diferentes para a mesma [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="has-x-large-font-size"><strong>Introdução</strong></p>



<p></p>



<p class="has-text-align-left">Em muitos ambientes Oracle, convivem dois mecanismos de agendamento: o <strong>DBMS_SCHEDULER</strong> (moderno) e o <strong>DBMS_JOB</strong> (legado). Cada um possui comandos, dicionários e semânticas próprios — &#8220;<code>enabled"</code> de um lado, &#8220;<code>broken</code>&#8221; do outro; <code>DBA_SCHEDULER_*</code> aqui, <code>DBA_JOBS*</code> ali; <code>STOP_JOB</code> vs. &#8220;matar sessão&#8221; etc.<br>O resultado, no dia a dia, é <strong>fricção operacional</strong>: consultas diferentes para a mesma pergunta, scripts paralelos para operações equivalentes, e uma curva de aprendizado desnecessária para tarefas simples como <strong>ver quem está rodando</strong>, <strong>habilitar/desabilitar</strong> e <strong>pausar um lote de jobs</strong> para uma janela de manutenção.</p>



<p class="has-text-align-left">Esta solução nasce exatamente desse cenário. O objetivo é oferecer um <strong>ponto único e transparente</strong> para <strong>inventariar, monitorar e operar</strong> ambos os mecanismos <strong>sem complexidade</strong>.<br>Você passa a consultar <strong>uma visão consolidada</strong> (inventário e execução), e a executar <strong>um pacote único</strong> para ações comuns — seja um job Scheduler com nome, seja um DBMS_JOB numérico.</p>



<p></p>



<p><br></p>



<h1 class="wp-block-heading">2) O que são DBMS_SCHEDULER e DBMS_JOB</h1>



<h2 class="wp-block-heading">DBMS_SCHEDULER (o mecanismo moderno)</h2>



<p>Introduzido para substituir o DBMS_JOB, o <strong>DBMS_SCHEDULER</strong> oferece uma arquitetura rica e modular:</p>



<ul class="wp-block-list">
<li><strong>Jobs, Programs e Schedules</strong> separados, possibilitando reuso e governança.</li>



<li><strong>Chains</strong> (fluxos com dependências), <strong>Windows</strong> e <strong>Job Classes</strong>.</li>



<li>Calendário expressivo por <code>repeat_interval</code> (calendar expressions).</li>



<li><strong>Parada controlada</strong> (<code>STOP_JOB</code>), logging detalhado, priorização e integração com Resource Manager.</li>



<li>Dicionário amplo (<code>DBA_SCHEDULER_JOBS</code>, <code>DBA_SCHEDULER_RUNNING_JOBS</code>, etc.).</li>
</ul>



<p>Em suma: mais recursos, rastreabilidade e controle fino. É o padrão recomendado para novas rotinas.</p>



<p><br></p>



<h2 class="wp-block-heading">DBMS_JOB (o mecanismo legado)</h2>



<p>O <strong>DBMS_JOB</strong> é mais simples e direto:</p>



<ul class="wp-block-list">
<li>Cada job tem um <strong>número</strong> (ex.: 128), um comando <strong>WHAT</strong> (PL/SQL a executar), um <strong>NEXT_DATE</strong> e um <strong>INTERVAL</strong> (string).</li>



<li>A disponibilidade é representada por <code>BROKEN = 'Y'|'N'</code> em vez de <code>ENABLED</code>.</li>



<li><strong>Não</strong> possui um comando nativo para parar execução em curso; na prática, usa-se o encerramento da <strong>sessão</strong> que executa o job.</li>



<li>Dicionário compacto (<code>DBA_JOBS</code>, <code>DBA_JOBS_RUNNING</code>).</li>
</ul>



<p>Embora menos flexível, é comum que ambientes antigos ainda mantenham rotinas estáveis sob DBMS_JOB.</p>



<p><br></p>



<h1 class="wp-block-heading">Vantagens de utilizar esta solução</h1>



<p><strong>1. Interface única e coerente</strong></p>



<ul class="wp-block-list">
<li><strong>Views consolidadas</strong> para inventário (<code>JOB_ADMIN_ALL_JOBS[_V]</code>) e execução (<code>JOB_ADMIN_RUNNING[_V]</code>) que mesclam Scheduler e DBMS_JOB.</li>



<li><strong>Colunas homogêneas</strong>: <code>enabled</code> sempre como TRUE/FALSE, datas e intervalos <strong>formatados</strong> nas versões “_V”.</li>
</ul>



<p><strong>2. Produtividade imediata</strong></p>



<ul class="wp-block-list">
<li>Uma consulta responde “o que tenho?”, “quando roda?”, “quem está rodando e há quanto tempo?”.</li>



<li>O operador <strong>não precisa lembrar</strong> se o job é Scheduler ou DBMS_JOB para consultar status ou executar ações.</li>
</ul>



<p><strong>3. Operação simples e segura</strong></p>



<ul class="wp-block-list">
<li><strong>Habilitar/Desabilitar</strong> por um único procedimento (<code>enable_job</code>/<code>disable_job</code>), passando <strong>nome</strong> (Scheduler) ou <strong>número</strong> (DBMS_JOB).</li>



<li><strong>Parada elegante</strong>: para Scheduler usa <code>STOP_JOB(force =&gt; TRUE)</code>; para DBMS_JOB, encerra a <strong>sessão</strong> de execução antes de mudar o estado (RAC-aware).</li>



<li><strong>Lote inteligente</strong> (<code>set_jobs_by_pattern</code>): aplique uma ação a um conjunto por <code>LIKE</code>, escolhendo tipo (Scheduler/DBMS_JOB/ANY) e se deve parar os ativos.</li>
</ul>



<p><strong>4. Observabilidade e padronização</strong></p>



<ul class="wp-block-list">
<li>Saídas de <code>list_jobs</code> e <code>list_running_jobs</code> são <strong>limpas e didáticas</strong>, integrando as duas tecnologias com o mesmo layout.</li>



<li>Facilita auditorias, health-checks e relatórios operacionais com <strong>menos scripts</strong>.</li>
</ul>



<p><strong>5. Governança simplificada</strong></p>



<ul class="wp-block-list">
<li><strong>Role única</strong> (<code>JOBDBMSSCHEDULERALL</code>) e <strong>sinônimos públicos</strong>: padroniza o consumo entre times e ferramentas.</li>



<li><code>AUTHID DEFINER</code>: quem usa não precisa de privilégio de DBA — basta receber a role.</li>
</ul>



<p><strong>6. Idempotência e baixa fricção de implantação</strong></p>



<ul class="wp-block-list">
<li><code>CREATE OR REPLACE</code> em todos os objetos e checagens defensivas: <strong>reexecutar reinstala</strong>.</li>



<li><strong>Compatível com RAC</strong> e com execução em <strong>PDB</strong> (quando aplicável).</li>
</ul>



<p><strong>7. Menor risco operacional</strong></p>



<ul class="wp-block-list">
<li>Mensagens claras e validações garantem que “job não encontrado” ou “nome ambíguo entre owners” sejam tratados com <strong>erros explicativos</strong>.</li>



<li>Em manutenção, <code>p_stop_running =&gt; TRUE</code> reduz inconsistências ao pausar um lote inteiro de forma controlada.</li>
</ul>



<p><strong>8. Porta de entrada para modernização</strong></p>



<ul class="wp-block-list">
<li>Ao dar visibilidade e controle unificado, a solução <strong>facilita migrações graduais</strong> de DBMS_JOB para DBMS_SCHEDULER, sem interrupção do dia a dia.</li>
</ul>



<p><br></p>



<p><em>Faça o download do instalador pkg_job_admin no link abaixo e habilite a gestão unificada de jobs Oracle.</em><br><br><br></p>



<div class="wp-block-file aligncenter"><a id="wp-block-file--media-5691fc75-8483-4dd2-a032-4fcb5a7fb647" href="https://furushima.com.br/wp-content/uploads/2025/09/job_admin_setup_completo.zip">Download &#8211; script pkg_job_admin &#8211; ORACLE</a><a href="https://furushima.com.br/wp-content/uploads/2025/09/job_admin_setup_completo.zip" class="wp-block-file__button wp-element-button" download aria-describedby="wp-block-file--media-5691fc75-8483-4dd2-a032-4fcb5a7fb647">Baixar</a></div>



<p><br><br><br></p>



<p class="has-large-font-size"><strong>Administração de jobs Oracle em um só lugar: Instalação e uso do pkg_job_admin</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="[ORCL.oracle@furushimait_labs ~]$ sqlplus / as sysdba

SQL*Plus: Release 19.0.0.0.0 - Production on Wed Sep 10 14:52:51 2025
Version 19.20.0.0.0

Copyright (c) 1982, 2022, Oracle.  All rights reserved.


Connected to:
Oracle Database 19c EE Extreme Perf Release 19.0.0.0.0 - Production
Version 19.20.0.0.0

SQL&gt; @job_admin_setup_completo.sql

═════════════════════════════════════════════════════════════════════════════════════════════
Iniciando job_admin_setup_completo.sql
═════════════════════════════════════════════════════════════════════════════════════════════
Owner atual: SYS

PL/SQL procedure successfully completed.


── 1) Criando/Atualizando Views Consolidadas …

View created.


View created.


View created.


View created.

✓ Views criadas/atualizadas com sucesso.

── 2) Criando/Atualizando Pacote (SPEC) …

Package created.

No errors.

── 3) Criando/Atualizando Pacote (BODY) …

Package body created.

No errors.
✓ Pacote criado/atualizado com sucesso.

── 4) Segurança: ROLE, Grants e Sinônimos Públicos …
Role JOBDBMSSCHEDULERALL já existente.

PL/SQL procedure successfully completed.


Grant succeeded.


Grant succeeded.


Grant succeeded.


Grant succeeded.


Grant succeeded.

Sinônimos públicos criados/atualizados.

PL/SQL procedure successfully completed.

✓ Segurança configurada (ROLE + grants + sinônimos públicos).

── 5) Auto-Validação (não intrusiva) …
Pacote PKG_JOB_ADMIN sem erros de compilação.

PL/SQL procedure successfully completed.

Views acessíveis: JOB_ADMIN_ALL_JOBS e JOB_ADMIN_RUNNING OK.

PL/SQL procedure successfully completed.


── 6) Exemplos de Uso para referência  …

-- Inventário:
BEGIN
pkg_job_admin.list_jobs;                          -- todos os jobs
pkg_job_admin.list_jobs('DEMOAPP');               -- por owner
pkg_job_admin.list_jobs(p_like =&gt; 'JOB_%');       -- por padrão (LIKE)
END
/
-- Em execução agora:
BEGIN
pkg_job_admin.list_running_jobs;                       -- tudo
pkg_job_admin.list_running_jobs('DEMOAPP');            -- por owner
pkg_job_admin.list_running_jobs(p_like =&gt; 'SYNC_%');   -- por padrão (LIKE)
END
/
-- Operações pontuais:
-- SCHEDULER (por nome; owner opcional se único no banco)
-- BEGIN
--   pkg_job_admin.disable_job('DEMOAPP.JOB_ATUALIZA_INDICES', p_stop_running =&gt; TRUE)
--   pkg_job_admin.enable_job ('DEMOAPP.JOB_ATUALIZA_INDICES')
-- END
-- /
-- DBMS_JOB (por número; owner apenas para validar pertinência quando desejar)
-- BEGIN
--   pkg_job_admin.disable_job('128', p_owner =&gt; 'SYS', p_stop_running =&gt; TRUE)
--   pkg_job_admin.enable_job ('128', p_owner =&gt; 'SYS')
-- END
-- /
-- Lote por padrão (por tipo):
-- BEGIN
--   pkg_job_admin.set_jobs_by_pattern(
--     p_name_like    =&gt; 'JOB_SYNC_%',
--     p_enable       =&gt; FALSE,
--     p_owner        =&gt; 'DEMOAPP',
--     p_type         =&gt; pkg_job_admin.c_type_scheduler, -- SCHEDULER | DBMS_JOB | ANY
--     p_stop_running =&gt; TRUE
--   )
-- END
-- /
-- Visões consolidadas:
-- SELECT * FROM job_admin_all_jobs_v ORDER BY owner, job_type, job_name
-- SELECT * FROM job_admin_running_v  ORDER BY running_instance, job_type, job_name

═════════════════════════════════════════════════════════════════════════════════════════════
Conclusão: job_admin_setup_completo.sql executado.
Para conceder a ROLE a um usuário final, utilize:
GRANT JOBDBMSSCHEDULERALL TO nome_do_usuario
═════════════════════════════════════════════════════════════════════════════════════════════
" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">[ORCL.oracle@furushimait_labs ~]$ sqlplus / </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> sysdba</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">SQL</span><span style="color: #D4D4D4">*Plus: Release </span><span style="color: #B5CEA8">19</span><span style="color: #D4D4D4">.</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">.</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">.</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">.</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> - Production </span><span style="color: #569CD6">on</span><span style="color: #D4D4D4"> Wed Sep </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">14</span><span style="color: #D4D4D4">:</span><span style="color: #B5CEA8">52</span><span style="color: #D4D4D4">:</span><span style="color: #B5CEA8">51</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">2025</span></span>
<span class="line"><span style="color: #569CD6">Version</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">19</span><span style="color: #D4D4D4">.</span><span style="color: #B5CEA8">20</span><span style="color: #D4D4D4">.</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">.</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">.</span><span style="color: #B5CEA8">0</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">Copyright (c) </span><span style="color: #B5CEA8">1982</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">2022</span><span style="color: #D4D4D4">, Oracle.  All rights reserved.</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">Connected </span><span style="color: #569CD6">to</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">Oracle </span><span style="color: #569CD6">Database</span><span style="color: #D4D4D4"> 19c EE Extreme Perf Release </span><span style="color: #B5CEA8">19</span><span style="color: #D4D4D4">.</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">.</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">.</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">.</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> - Production</span></span>
<span class="line"><span style="color: #569CD6">Version</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">19</span><span style="color: #D4D4D4">.</span><span style="color: #B5CEA8">20</span><span style="color: #D4D4D4">.</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">.</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">.</span><span style="color: #B5CEA8">0</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">SQL</span><span style="color: #D4D4D4">&gt; @job_admin_setup_completo.</span><span style="color: #569CD6">sql</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">═════════════════════════════════════════════════════════════════════════════════════════════</span></span>
<span class="line"><span style="color: #D4D4D4">Iniciando job_admin_setup_completo.sql</span></span>
<span class="line"><span style="color: #D4D4D4">═════════════════════════════════════════════════════════════════════════════════════════════</span></span>
<span class="line"><span style="color: #569CD6">Owner</span><span style="color: #D4D4D4"> atual: SYS</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">PL/</span><span style="color: #569CD6">SQL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">procedure</span><span style="color: #D4D4D4"> successfully completed.</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">── </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">) Criando/Atualizando Views Consolidadas …</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">View created.</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">View created.</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">View created.</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">View created.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">✓ Views criadas/atualizadas com sucesso.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">── </span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">) Criando/Atualizando Pacote (SPEC) …</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">Package created.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">No</span><span style="color: #D4D4D4"> errors.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">── </span><span style="color: #B5CEA8">3</span><span style="color: #D4D4D4">) Criando/Atualizando Pacote (BODY) …</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">Package body created.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">No</span><span style="color: #D4D4D4"> errors.</span></span>
<span class="line"><span style="color: #D4D4D4">✓ Pacote criado/atualizado com sucesso.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">── </span><span style="color: #B5CEA8">4</span><span style="color: #D4D4D4">) Segurança: </span><span style="color: #569CD6">ROLE</span><span style="color: #D4D4D4">, Grants e Sinônimos Públicos …</span></span>
<span class="line"><span style="color: #569CD6">Role</span><span style="color: #D4D4D4"> JOBDBMSSCHEDULERALL já existente.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">PL/</span><span style="color: #569CD6">SQL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">procedure</span><span style="color: #D4D4D4"> successfully completed.</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">Grant</span><span style="color: #D4D4D4"> succeeded.</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">Grant</span><span style="color: #D4D4D4"> succeeded.</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">Grant</span><span style="color: #D4D4D4"> succeeded.</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">Grant</span><span style="color: #D4D4D4"> succeeded.</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">Grant</span><span style="color: #D4D4D4"> succeeded.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">Sinônimos públicos criados/atualizados.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">PL/</span><span style="color: #569CD6">SQL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">procedure</span><span style="color: #D4D4D4"> successfully completed.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">✓ Segurança configurada (</span><span style="color: #569CD6">ROLE</span><span style="color: #D4D4D4"> + grants + sinônimos públicos).</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">── </span><span style="color: #B5CEA8">5</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">Auto</span><span style="color: #D4D4D4">-Validação (não intrusiva) …</span></span>
<span class="line"><span style="color: #D4D4D4">Pacote PKG_JOB_ADMIN sem erros de compilação.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">PL/</span><span style="color: #569CD6">SQL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">procedure</span><span style="color: #D4D4D4"> successfully completed.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">Views acessíveis: JOB_ADMIN_ALL_JOBS e JOB_ADMIN_RUNNING OK.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">PL/</span><span style="color: #569CD6">SQL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">procedure</span><span style="color: #D4D4D4"> successfully completed.</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">── </span><span style="color: #B5CEA8">6</span><span style="color: #D4D4D4">) Exemplos de Uso para referência  …</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">-- Inventário:</span></span>
<span class="line"><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">pkg_job_admin.list_jobs;                          </span><span style="color: #6A9955">-- todos os jobs</span></span>
<span class="line"><span style="color: #D4D4D4">pkg_job_admin.list_jobs(</span><span style="color: #CE9178">&#39;DEMOAPP&#39;</span><span style="color: #D4D4D4">);               </span><span style="color: #6A9955">-- por owner</span></span>
<span class="line"><span style="color: #D4D4D4">pkg_job_admin.list_jobs(p_like =&gt; </span><span style="color: #CE9178">&#39;JOB_%&#39;</span><span style="color: #D4D4D4">);       </span><span style="color: #6A9955">-- por padrão (LIKE)</span></span>
<span class="line"><span style="color: #569CD6">END</span></span>
<span class="line"><span style="color: #D4D4D4">/</span></span>
<span class="line"><span style="color: #6A9955">-- Em execução agora:</span></span>
<span class="line"><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">pkg_job_admin.list_running_jobs;                       </span><span style="color: #6A9955">-- tudo</span></span>
<span class="line"><span style="color: #D4D4D4">pkg_job_admin.list_running_jobs(</span><span style="color: #CE9178">&#39;DEMOAPP&#39;</span><span style="color: #D4D4D4">);            </span><span style="color: #6A9955">-- por owner</span></span>
<span class="line"><span style="color: #D4D4D4">pkg_job_admin.list_running_jobs(p_like =&gt; </span><span style="color: #CE9178">&#39;SYNC_%&#39;</span><span style="color: #D4D4D4">);   </span><span style="color: #6A9955">-- por padrão (LIKE)</span></span>
<span class="line"><span style="color: #569CD6">END</span></span>
<span class="line"><span style="color: #D4D4D4">/</span></span>
<span class="line"><span style="color: #6A9955">-- Operações pontuais:</span></span>
<span class="line"><span style="color: #6A9955">-- SCHEDULER (por nome; owner opcional se único no banco)</span></span>
<span class="line"><span style="color: #6A9955">-- BEGIN</span></span>
<span class="line"><span style="color: #6A9955">--   pkg_job_admin.disable_job(&#39;DEMOAPP.JOB_ATUALIZA_INDICES&#39;, p_stop_running =&gt; TRUE)</span></span>
<span class="line"><span style="color: #6A9955">--   pkg_job_admin.enable_job (&#39;DEMOAPP.JOB_ATUALIZA_INDICES&#39;)</span></span>
<span class="line"><span style="color: #6A9955">-- END</span></span>
<span class="line"><span style="color: #6A9955">-- /</span></span>
<span class="line"><span style="color: #6A9955">-- DBMS_JOB (por número; owner apenas para validar pertinência quando desejar)</span></span>
<span class="line"><span style="color: #6A9955">-- BEGIN</span></span>
<span class="line"><span style="color: #6A9955">--   pkg_job_admin.disable_job(&#39;128&#39;, p_owner =&gt; &#39;SYS&#39;, p_stop_running =&gt; TRUE)</span></span>
<span class="line"><span style="color: #6A9955">--   pkg_job_admin.enable_job (&#39;128&#39;, p_owner =&gt; &#39;SYS&#39;)</span></span>
<span class="line"><span style="color: #6A9955">-- END</span></span>
<span class="line"><span style="color: #6A9955">-- /</span></span>
<span class="line"><span style="color: #6A9955">-- Lote por padrão (por tipo):</span></span>
<span class="line"><span style="color: #6A9955">-- BEGIN</span></span>
<span class="line"><span style="color: #6A9955">--   pkg_job_admin.set_jobs_by_pattern(</span></span>
<span class="line"><span style="color: #6A9955">--     p_name_like    =&gt; &#39;JOB_SYNC_%&#39;,</span></span>
<span class="line"><span style="color: #6A9955">--     p_enable       =&gt; FALSE,</span></span>
<span class="line"><span style="color: #6A9955">--     p_owner        =&gt; &#39;DEMOAPP&#39;,</span></span>
<span class="line"><span style="color: #6A9955">--     p_type         =&gt; pkg_job_admin.c_type_scheduler, -- SCHEDULER | DBMS_JOB | ANY</span></span>
<span class="line"><span style="color: #6A9955">--     p_stop_running =&gt; TRUE</span></span>
<span class="line"><span style="color: #6A9955">--   )</span></span>
<span class="line"><span style="color: #6A9955">-- END</span></span>
<span class="line"><span style="color: #6A9955">-- /</span></span>
<span class="line"><span style="color: #6A9955">-- Visões consolidadas:</span></span>
<span class="line"><span style="color: #6A9955">-- SELECT * FROM job_admin_all_jobs_v ORDER BY owner, job_type, job_name</span></span>
<span class="line"><span style="color: #6A9955">-- SELECT * FROM job_admin_running_v  ORDER BY running_instance, job_type, job_name</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">═════════════════════════════════════════════════════════════════════════════════════════════</span></span>
<span class="line"><span style="color: #D4D4D4">Conclusão: job_admin_setup_completo.sql executado.</span></span>
<span class="line"><span style="color: #D4D4D4">Para conceder a </span><span style="color: #569CD6">ROLE</span><span style="color: #D4D4D4"> a um usuário final, utilize:</span></span>
<span class="line"><span style="color: #569CD6">GRANT</span><span style="color: #D4D4D4"> JOBDBMSSCHEDULERALL </span><span style="color: #569CD6">TO</span><span style="color: #D4D4D4"> nome_do_usuario</span></span>
<span class="line"><span style="color: #D4D4D4">═════════════════════════════════════════════════════════════════════════════════════════════</span></span>
<span class="line"></span></code></pre></div>



<p><br><br><br></p>



<h2 class="wp-block-heading">O que o script cria</h2>



<h3 class="wp-block-heading"></h3>



<h3 class="wp-block-heading">Objetos de dados (Views)</h3>



<ul class="wp-block-list">
<li><code>JOB_ADMIN_ALL_JOBS</code> — Inventário <strong>unificado</strong> (SCHEDULER + DBMS_JOB).</li>



<li><code>JOB_ADMIN_RUNNING</code> — Execução <strong>unificada</strong> no momento (SCHEDULER + DBMS_JOB).</li>



<li><code>JOB_ADMIN_ALL_JOBS_V</code> — Versão &#8220;amigável&#8221; do inventário (datas e intervalos formatados).</li>



<li><code>JOB_ADMIN_RUNNING_V</code> — Versão &#8220;amigável&#8221; da execução (intervalos formatados).</li>
</ul>



<h3 class="wp-block-heading">API (Package)</h3>



<ul class="wp-block-list">
<li><code>PKG_JOB_ADMIN</code> — Procedimentos para listar, habilitar/desabilitar e controlar lotes.
<ul class="wp-block-list">
<li><code>list_jobs(p_owner, p_like)</code></li>



<li><code>list_running_jobs(p_owner, p_like)</code></li>



<li><code>set_job_enabled(p_job_identifier, p_enable, p_owner, p_stop_running)</code></li>



<li><code>enable_job(...)</code> / <code>disable_job(...)</code></li>



<li><code>set_jobs_by_pattern(p_name_like, p_enable, p_owner, p_type, p_stop_running)</code></li>



<li>Constantes: <code>c_type_scheduler</code>, <code>c_type_dbms_job</code>, <code>c_type_any</code></li>
</ul>
</li>
</ul>



<h3 class="wp-block-heading"></h3>



<p><br><br><br></p>



<p class="has-medium-font-size"><strong>Inventário consolidado, pronto para relatório</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro alignwide" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="SELECT 
  owner, 
  job_type, 
  job_name, 
  enabled, 
  state, 
  next_run_date 
FROM 
  job_admin_all_jobs_v 
ORDER BY 
  owner, 
  job_type, 
  job_name;
" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4">, </span></span>
<span class="line"><span style="color: #D4D4D4">  job_type, </span></span>
<span class="line"><span style="color: #D4D4D4">  job_name, </span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">enabled</span><span style="color: #D4D4D4">, </span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">state</span><span style="color: #D4D4D4">, </span></span>
<span class="line"><span style="color: #D4D4D4">  next_run_date </span></span>
<span class="line"><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">  job_admin_all_jobs_v </span></span>
<span class="line"><span style="color: #569CD6">ORDER BY</span><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4">, </span></span>
<span class="line"><span style="color: #D4D4D4">  job_type, </span></span>
<span class="line"><span style="color: #D4D4D4">  job_name;</span></span>
<span class="line"></span></code></pre></div>



<p></p>



<p></p>



<h2 class="wp-block-heading"></h2>



<p></p>



<p class="has-medium-font-size"><strong>Execução no momento (quem está rodando agora)</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro alignwide" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="SELECT 
  owner, 
  job_type, 
  job_name, 
  running_instance, 
  elapsed_time 
FROM 
  job_admin_running_v 
ORDER BY 
  running_instance, 
  job_type, 
  job_name;
" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4">, </span></span>
<span class="line"><span style="color: #D4D4D4">  job_type, </span></span>
<span class="line"><span style="color: #D4D4D4">  job_name, </span></span>
<span class="line"><span style="color: #D4D4D4">  running_instance, </span></span>
<span class="line"><span style="color: #D4D4D4">  elapsed_time </span></span>
<span class="line"><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">  job_admin_running_v </span></span>
<span class="line"><span style="color: #569CD6">ORDER BY</span><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">  running_instance, </span></span>
<span class="line"><span style="color: #D4D4D4">  job_type, </span></span>
<span class="line"><span style="color: #D4D4D4">  job_name;</span></span>
<span class="line"></span></code></pre></div>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<h2 class="wp-block-heading"></h2>



<h2 class="wp-block-heading"></h2>



<p></p>
</blockquote>



<p></p>



<h2 class="wp-block-heading"></h2>



<p><br><br><br><br></p>



<p class="has-medium-font-size"><strong>Habilitar/Desabilitar individualmente</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro alignwide" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="-- DBMS_SCHEDULER por nome (com owner)
BEGIN
  pkg_job_admin.disable_job('DEMOAPP.JOB_XPTO_ETL_DIARIO', p_stop_running =&gt; TRUE);
  pkg_job_admin.enable_job ('DEMOAPP.JOB_XPTO_ETL_DIARIO');
END;
/


-- DBMS_JOB por número (com validação de owner opcional)
BEGIN
  pkg_job_admin.disable_job('128', p_owner =&gt; 'SYS', p_stop_running =&gt; TRUE);
  pkg_job_admin.enable_job ('128', p_owner =&gt; 'SYS');
END;
/" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">-- DBMS_SCHEDULER por nome (com owner)</span></span>
<span class="line"><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">  pkg_job_admin.disable_job(</span><span style="color: #CE9178">&#39;DEMOAPP.JOB_XPTO_ETL_DIARIO&#39;</span><span style="color: #D4D4D4">, p_stop_running =&gt; TRUE);</span></span>
<span class="line"><span style="color: #D4D4D4">  pkg_job_admin.enable_job (</span><span style="color: #CE9178">&#39;DEMOAPP.JOB_XPTO_ETL_DIARIO&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">/</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">-- DBMS_JOB por número (com validação de owner opcional)</span></span>
<span class="line"><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">  pkg_job_admin.disable_job(</span><span style="color: #CE9178">&#39;128&#39;</span><span style="color: #D4D4D4">, p_owner =&gt; </span><span style="color: #CE9178">&#39;SYS&#39;</span><span style="color: #D4D4D4">, p_stop_running =&gt; TRUE);</span></span>
<span class="line"><span style="color: #D4D4D4">  pkg_job_admin.enable_job (</span><span style="color: #CE9178">&#39;128&#39;</span><span style="color: #D4D4D4">, p_owner =&gt; </span><span style="color: #CE9178">&#39;SYS&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">/</span></span></code></pre></div>



<p><br></p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><br></p>
</blockquote>



<p></p>



<p></p>



<p><br><br></p>



<h2 class="wp-block-heading"></h2>



<p></p>



<p class="has-medium-font-size"><strong>Habilitar/Desabilitar JOBS em lote </strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro alignwide" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="BEGIN
  pkg_job_admin.set_jobs_by_pattern(
    p_name_like    =&gt; 'JOB_XPTO_%',
    p_enable       =&gt; FALSE,                            -- desativar todos que casem com o padrão
    p_owner        =&gt; 'DEMOAPP',                        -- opcional
    p_type         =&gt; pkg_job_admin.c_type_scheduler,   -- QUALQUER TIPO : SCHEDULER | DBMS_JOB | ANY
    p_stop_running =&gt; TRUE
  );
END;
/" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">  pkg_job_admin.set_jobs_by_pattern(</span></span>
<span class="line"><span style="color: #D4D4D4">    p_name_like    =&gt; </span><span style="color: #CE9178">&#39;JOB_XPTO_%&#39;</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">    p_enable       =&gt; FALSE,                            </span><span style="color: #6A9955">-- desativar todos que casem com o padrão</span></span>
<span class="line"><span style="color: #D4D4D4">    p_owner        =&gt; </span><span style="color: #CE9178">&#39;DEMOAPP&#39;</span><span style="color: #D4D4D4">,                        </span><span style="color: #6A9955">-- opcional</span></span>
<span class="line"><span style="color: #D4D4D4">    p_type         =&gt; pkg_job_admin.c_type_scheduler,   </span><span style="color: #6A9955">-- QUALQUER TIPO : SCHEDULER | DBMS_JOB | ANY</span></span>
<span class="line"><span style="color: #D4D4D4">    p_stop_running =&gt; TRUE</span></span>
<span class="line"><span style="color: #D4D4D4">  );</span></span>
<span class="line"><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">/</span></span></code></pre></div>



<p><br><br><br></p>



<p></p>



<p><br></p>



<p class="has-medium-font-size"><strong>Quais jobs existem e quando rodarão?</strong></p>



<p></p>



<div class="wp-block-kevinbatdorf-code-block-pro alignwide" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="SELECT owner, job_type, job_name, enabled, state, next_run_date 
FROM   job_admin_all_jobs_v
ORDER  BY owner, job_type, job_name;


--  O que observar
--    • job_type: distingue SCHEDULER vs DBMS_JOB.
--    • enabled: “TRUE/FALSE” consolidado para ambos.
--    • state: útil para SCHEDULER (ex.: SCHEDULED, DISABLED)." style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4">, job_type, job_name, </span><span style="color: #569CD6">enabled</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">state</span><span style="color: #D4D4D4">, next_run_date </span></span>
<span class="line"><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4">   job_admin_all_jobs_v</span></span>
<span class="line"><span style="color: #569CD6">ORDER  BY</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4">, job_type, job_name;</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">--  O que observar</span></span>
<span class="line"><span style="color: #6A9955">--    • job_type: distingue SCHEDULER vs DBMS_JOB.</span></span>
<span class="line"><span style="color: #6A9955">--    • enabled: “TRUE/FALSE” consolidado para ambos.</span></span>
<span class="line"><span style="color: #6A9955">--    • state: útil para SCHEDULER (ex.: SCHEDULED, DISABLED).</span></span></code></pre></div>



<p><br><br><br></p>



<p></p>



<p><br></p>



<p class="has-medium-font-size"><strong>Quais jobs contêm a palavra &#8216;XPTO&#8217; no nome ou no comando?</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro alignwide" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="SELECT owner, job_type, job_name, enabled, job_action
FROM   job_admin_all_jobs
WHERE  UPPER(job_name)   LIKE '%XPTO%'
   OR  UPPER(job_action) LIKE '%XPTO%'
ORDER  BY owner, job_name;" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4">, job_type, job_name, </span><span style="color: #569CD6">enabled</span><span style="color: #D4D4D4">, job_action</span></span>
<span class="line"><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4">   job_admin_all_jobs</span></span>
<span class="line"><span style="color: #569CD6">WHERE</span><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(job_name)   </span><span style="color: #569CD6">LIKE</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;%XPTO%&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">OR</span><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(job_action) </span><span style="color: #569CD6">LIKE</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;%XPTO%&#39;</span></span>
<span class="line"><span style="color: #569CD6">ORDER  BY</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4">, job_name;</span></span></code></pre></div>



<p><br></p>



<p><br><br><br><br><br></p>



<p><br></p>



<p class="has-medium-font-size"><strong>Qual o próximo agendamento dos jobs do meu schema de aplicação?</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro alignwide" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="SELECT job_name, enabled, state, next_run_date
FROM   job_admin_all_jobs_v
WHERE  owner = 'DEMOAPP'
ORDER  BY job_name;" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> job_name, </span><span style="color: #569CD6">enabled</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">state</span><span style="color: #D4D4D4">, next_run_date</span></span>
<span class="line"><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4">   job_admin_all_jobs_v</span></span>
<span class="line"><span style="color: #569CD6">WHERE</span><span style="color: #D4D4D4">  </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&#39;DEMOAPP&#39;</span></span>
<span class="line"><span style="color: #569CD6">ORDER  BY</span><span style="color: #D4D4D4"> job_name;</span></span></code></pre></div>



<p><br></p>



<p><br><br><br><br></p>



<p></p>



<p class="has-medium-font-size"><strong>Quem está rodando agora e há quanto tempo?</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro alignwide" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="SELECT owner, job_type, job_name, running_instance, elapsed_time
FROM   job_admin_running_v
ORDER  BY running_instance, job_type, job_name;" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4">, job_type, job_name, running_instance, elapsed_time</span></span>
<span class="line"><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4">   job_admin_running_v</span></span>
<span class="line"><span style="color: #569CD6">ORDER  BY</span><span style="color: #D4D4D4"> running_instance, job_type, job_name;</span></span></code></pre></div>



<p><br></p>



<p><br><br><br></p>



<p></p>



<p class="has-medium-font-size"><strong>Agora vamos ver se o job JOB_XPTO_ETL_DIARIO está rodando e há quanto tempo</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro alignwide" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="SELECT owner, job_type, job_name, elapsed_time
FROM   job_admin_running_v
WHERE  job_name = 'JOB_XPTO_ETL_DIARIO';

-- • Se vier linha, o job está ativo; elapsed_time mostra a duração no formato DD HH:MI:SS." style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4">, job_type, job_name, elapsed_time</span></span>
<span class="line"><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4">   job_admin_running_v</span></span>
<span class="line"><span style="color: #569CD6">WHERE</span><span style="color: #D4D4D4">  job_name = </span><span style="color: #CE9178">&#39;JOB_XPTO_ETL_DIARIO&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">-- • Se vier linha, o job está ativo; elapsed_time mostra a duração no formato DD HH:MI:SS.</span></span></code></pre></div>



<p><br></p>



<p><br><br><br></p>



<p></p>



<p class="has-medium-font-size"><strong>Quais jobs estão desabilitados, para uma revisão rápida?</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro alignwide" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="SELECT owner, job_type, job_name, enabled
FROM   job_admin_all_jobs_v
WHERE  enabled = 'FALSE'
ORDER  BY owner, job_type, job_name;" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4">, job_type, job_name, </span><span style="color: #569CD6">enabled</span></span>
<span class="line"><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4">   job_admin_all_jobs_v</span></span>
<span class="line"><span style="color: #569CD6">WHERE</span><span style="color: #D4D4D4">  </span><span style="color: #569CD6">enabled</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&#39;FALSE&#39;</span></span>
<span class="line"><span style="color: #569CD6">ORDER  BY</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4">, job_type, job_name;</span></span></code></pre></div>



<p><br></p>



<p><br><br><br></p>



<p></p>



<p class="has-large-font-size"><strong>Como usar o Pacote (exemplos passo a passo)</strong></p>



<p>Todos os exemplos assumem que você possui a role JOBDBMSSCHEDULERALL.<br>Use os sinônimos públicos (pkg_job_admin) — não há necessidade de prefixar com schema.</p>



<div class="wp-block-kevinbatdorf-code-block-pro alignwide" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="-- Inventário

BEGIN
  pkg_job_admin.list_jobs;                    -- Listar TUDO!
  pkg_job_admin.list_jobs('DEMOAPP');         -- Procurar pelo OWNER
  pkg_job_admin.list_jobs(p_like =&gt; 'JOB_%'); -- Busca por jobs cujo nome contenha o padrão informado (equivalente ao LIKE).
END;
/



--- OUTPUT : 

=== JOBS (SCHEDULER) ===
DEMOAPP.JOB_XPTO_ETL_DIARIO | enabled=TRUE | state=SCHEDULED | next=2025-09-27 01:00:00 | action=BEGIN pkg_etl.run_daily; END;
DEMOAPP.JOB_SYNC_CLIENTES   | enabled=FALSE | state=DISABLED | next=- | action=BEGIN sync_clientes(); END;

=== JOBS (DBMS_JOB) ===
DEMOAPP.128 | enabled=TRUE | next=2025-09-11 03:00:00 | what=BEGIN antiga_rotina(); END;" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">-- Inventário</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">  pkg_job_admin.list_jobs;                    </span><span style="color: #6A9955">-- Listar TUDO!</span></span>
<span class="line"><span style="color: #D4D4D4">  pkg_job_admin.list_jobs(</span><span style="color: #CE9178">&#39;DEMOAPP&#39;</span><span style="color: #D4D4D4">);         </span><span style="color: #6A9955">-- Procurar pelo OWNER</span></span>
<span class="line"><span style="color: #D4D4D4">  pkg_job_admin.list_jobs(p_like =&gt; </span><span style="color: #CE9178">&#39;JOB_%&#39;</span><span style="color: #D4D4D4">); </span><span style="color: #6A9955">-- Busca por jobs cujo nome contenha o padrão informado (equivalente ao LIKE).</span></span>
<span class="line"><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">/</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">--- OUTPUT : </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">=== JOBS (SCHEDULER) ===</span></span>
<span class="line"><span style="color: #D4D4D4">DEMOAPP.JOB_XPTO_ETL_DIARIO | </span><span style="color: #569CD6">enabled</span><span style="color: #D4D4D4">=TRUE | </span><span style="color: #569CD6">state</span><span style="color: #D4D4D4">=SCHEDULED | </span><span style="color: #569CD6">next</span><span style="color: #D4D4D4">=</span><span style="color: #B5CEA8">2025</span><span style="color: #D4D4D4">-</span><span style="color: #B5CEA8">09</span><span style="color: #D4D4D4">-</span><span style="color: #B5CEA8">27</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">01</span><span style="color: #D4D4D4">:</span><span style="color: #B5CEA8">00</span><span style="color: #D4D4D4">:</span><span style="color: #B5CEA8">00</span><span style="color: #D4D4D4"> | </span><span style="color: #569CD6">action</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">BEGIN</span><span style="color: #D4D4D4"> pkg_etl.run_daily; </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">DEMOAPP.JOB_SYNC_CLIENTES   | </span><span style="color: #569CD6">enabled</span><span style="color: #D4D4D4">=FALSE | </span><span style="color: #569CD6">state</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">DISABLED</span><span style="color: #D4D4D4"> | </span><span style="color: #569CD6">next</span><span style="color: #D4D4D4">=- | </span><span style="color: #569CD6">action</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">BEGIN</span><span style="color: #D4D4D4"> sync_clientes(); </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">=== JOBS (DBMS_JOB) ===</span></span>
<span class="line"><span style="color: #D4D4D4">DEMOAPP.128 | </span><span style="color: #569CD6">enabled</span><span style="color: #D4D4D4">=TRUE | </span><span style="color: #569CD6">next</span><span style="color: #D4D4D4">=</span><span style="color: #B5CEA8">2025</span><span style="color: #D4D4D4">-</span><span style="color: #B5CEA8">09</span><span style="color: #D4D4D4">-</span><span style="color: #B5CEA8">11</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">03</span><span style="color: #D4D4D4">:</span><span style="color: #B5CEA8">00</span><span style="color: #D4D4D4">:</span><span style="color: #B5CEA8">00</span><span style="color: #D4D4D4"> | what=</span><span style="color: #569CD6">BEGIN</span><span style="color: #D4D4D4"> antiga_rotina(); </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<p><br></p>



<p><br><br><br><br></p>



<p></p>



<p class="has-medium-font-size"><strong>Execução (quem está rodando) com leitura guiada</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro alignwide" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="-- Agora vamos ver se o job XPTO está rodando e há quanto tempo

BEGIN
  pkg_job_admin.list_running_jobs(p_like =&gt; 'JOB_XPTO_%');
END;
/



--- OUTPUT : 

=== RUNNING (SCHEDULER) ===
DEMOAPP.JOB_XPTO_ETL_DIARIO | sid=123 | inst=1 | elapsed=00 00:07:32 | cpu=00 00:02:10

=== RUNNING (DBMS_JOB) ===
-- (vazio, se nada estiver executando)" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">-- Agora vamos ver se o job XPTO está rodando e há quanto tempo</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">  pkg_job_admin.list_running_jobs(p_like =&gt; </span><span style="color: #CE9178">&#39;JOB_XPTO_%&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">/</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">--- OUTPUT : </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">=== RUNNING (SCHEDULER) ===</span></span>
<span class="line"><span style="color: #D4D4D4">DEMOAPP.JOB_XPTO_ETL_DIARIO | </span><span style="color: #569CD6">sid</span><span style="color: #D4D4D4">=</span><span style="color: #B5CEA8">123</span><span style="color: #D4D4D4"> | inst=</span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> | elapsed=</span><span style="color: #B5CEA8">00</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">00</span><span style="color: #D4D4D4">:</span><span style="color: #B5CEA8">07</span><span style="color: #D4D4D4">:</span><span style="color: #B5CEA8">32</span><span style="color: #D4D4D4"> | cpu=</span><span style="color: #B5CEA8">00</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">00</span><span style="color: #D4D4D4">:</span><span style="color: #B5CEA8">02</span><span style="color: #D4D4D4">:</span><span style="color: #B5CEA8">10</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">=== RUNNING (DBMS_JOB) ===</span></span>
<span class="line"><span style="color: #6A9955">-- (vazio, se nada estiver executando)</span></span></code></pre></div>



<p><br></p>



<p><br><br><br><br></p>



<p></p>



<p class="has-medium-font-size"><strong>Operações pontuais: habilitar/desabilitar</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro alignwide" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="-- DBMS_SCHEDULER por nome (owner informado — mais explícito):

BEGIN
  -- desativar e forçar parada se estiver rodando
  pkg_job_admin.disable_job('DEMOAPP.JOB_XPTO_ETL_DIARIO', p_stop_running =&gt; TRUE);
  -- reativar
  pkg_job_admin.enable_job ('DEMOAPP.JOB_XPTO_ETL_DIARIO');
END;
/



--- DBMS_JOB por número (owner opcional, útil para validar pertinência):

BEGIN
  -- desativar e forçar parada se estiver rodando
  pkg_job_admin.disable_job('128', p_owner =&gt; 'DEMOAPP', p_stop_running =&gt; TRUE);
  -- reativar
  pkg_job_admin.enable_job ('128', p_owner =&gt; 'DEMOAPP');
END;
/



-- O que acontece por trás:
--   • SCHEDULER: STOP_JOB(..., force =&gt; TRUE) (se p_stop_running=&gt;TRUE), seguido de DISABLE/ENABLE.
--   • DBMS_JOB: encerra sessão (se ativa) e marca BROKEN (NOT p_enable).
" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">-- DBMS_SCHEDULER por nome (owner informado — mais explícito):</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- desativar e forçar parada se estiver rodando</span></span>
<span class="line"><span style="color: #D4D4D4">  pkg_job_admin.disable_job(</span><span style="color: #CE9178">&#39;DEMOAPP.JOB_XPTO_ETL_DIARIO&#39;</span><span style="color: #D4D4D4">, p_stop_running =&gt; TRUE);</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- reativar</span></span>
<span class="line"><span style="color: #D4D4D4">  pkg_job_admin.enable_job (</span><span style="color: #CE9178">&#39;DEMOAPP.JOB_XPTO_ETL_DIARIO&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">/</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">--- DBMS_JOB por número (owner opcional, útil para validar pertinência):</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- desativar e forçar parada se estiver rodando</span></span>
<span class="line"><span style="color: #D4D4D4">  pkg_job_admin.disable_job(</span><span style="color: #CE9178">&#39;128&#39;</span><span style="color: #D4D4D4">, p_owner =&gt; </span><span style="color: #CE9178">&#39;DEMOAPP&#39;</span><span style="color: #D4D4D4">, p_stop_running =&gt; TRUE);</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- reativar</span></span>
<span class="line"><span style="color: #D4D4D4">  pkg_job_admin.enable_job (</span><span style="color: #CE9178">&#39;128&#39;</span><span style="color: #D4D4D4">, p_owner =&gt; </span><span style="color: #CE9178">&#39;DEMOAPP&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">/</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">-- O que acontece por trás:</span></span>
<span class="line"><span style="color: #6A9955">--   • SCHEDULER: STOP_JOB(..., force =&gt; TRUE) (se p_stop_running=&gt;TRUE), seguido de DISABLE/ENABLE.</span></span>
<span class="line"><span style="color: #6A9955">--   • DBMS_JOB: encerra sessão (se ativa) e marca BROKEN (NOT p_enable).</span></span>
<span class="line"></span></code></pre></div>



<p><br></p>



<p><br><br><br><br></p>



<p class="has-medium-font-size"><strong>Operações em lote: desabilitar todos os “JOB_XPTO_%” do SCHEDULER</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro alignwide" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="-- Cenário: janela de manutenção requer pausar rotinas XPTO do schema de aplicação.

--- Desativar
BEGIN
  pkg_job_admin.set_jobs_by_pattern(
    p_name_like    =&gt; 'JOB_XPTO_%',
    p_enable       =&gt; FALSE,                              -- desativar
    p_owner        =&gt; 'DEMOAPP',
    p_type         =&gt; pkg_job_admin.c_type_scheduler,     
    p_stop_running =&gt; TRUE                                -- encerrar active session job
  );
END;
/



--- Reativar
BEGIN
  pkg_job_admin.set_jobs_by_pattern(
    p_name_like    =&gt; 'JOB_XPTO_%',
    p_enable       =&gt; TRUE,                               -- reativar
    p_owner        =&gt; 'DEMOAPP',
    p_type         =&gt; pkg_job_admin.c_type_scheduler
  );
END;
/

" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">-- Cenário: janela de manutenção requer pausar rotinas XPTO do schema de aplicação.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">--- Desativar</span></span>
<span class="line"><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">  pkg_job_admin.set_jobs_by_pattern(</span></span>
<span class="line"><span style="color: #D4D4D4">    p_name_like    =&gt; </span><span style="color: #CE9178">&#39;JOB_XPTO_%&#39;</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">    p_enable       =&gt; FALSE,                              </span><span style="color: #6A9955">-- desativar</span></span>
<span class="line"><span style="color: #D4D4D4">    p_owner        =&gt; </span><span style="color: #CE9178">&#39;DEMOAPP&#39;</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">    p_type         =&gt; pkg_job_admin.c_type_scheduler,     </span></span>
<span class="line"><span style="color: #D4D4D4">    p_stop_running =&gt; TRUE                                </span><span style="color: #6A9955">-- encerrar active session job</span></span>
<span class="line"><span style="color: #D4D4D4">  );</span></span>
<span class="line"><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">/</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">--- Reativar</span></span>
<span class="line"><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">  pkg_job_admin.set_jobs_by_pattern(</span></span>
<span class="line"><span style="color: #D4D4D4">    p_name_like    =&gt; </span><span style="color: #CE9178">&#39;JOB_XPTO_%&#39;</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">    p_enable       =&gt; TRUE,                               </span><span style="color: #6A9955">-- reativar</span></span>
<span class="line"><span style="color: #D4D4D4">    p_owner        =&gt; </span><span style="color: #CE9178">&#39;DEMOAPP&#39;</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">    p_type         =&gt; pkg_job_admin.c_type_scheduler</span></span>
<span class="line"><span style="color: #D4D4D4">  );</span></span>
<span class="line"><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">/</span></span>
<span class="line"></span>
<span class="line"></span></code></pre></div>



<p><br></p>



<p><br><br><br><br></p>



<p></p>



<p class="has-medium-font-size"><strong>Analisar o job &#8216;JOB_XPTO_ETL_DIARIO&#8217; especificamente</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro alignwide" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="-- 1. Está presente? Quando roda?

SELECT *
FROM   job_admin_all_jobs_v
WHERE  owner = 'DEMOAPP' AND job_name = 'JOB_XPTO_ETL_DIARIO';


-- 2. Está executando agora? Há quanto tempo?
SELECT running_instance, elapsed_time
FROM   job_admin_running_v
WHERE  owner = 'DEMOAPP' AND job_name = 'JOB_XPTO_ETL_DIARIO';

-- 3. Pausar com segurança (parar se ativo, depois desabilitar)
BEGIN
  pkg_job_admin.disable_job('DEMOAPP.JOB_XPTO_ETL_DIARIO', p_stop_running =&gt; TRUE);
END;
/

-- 4. Reativar
BEGIN
  pkg_job_admin.enable_job('DEMOAPP.JOB_XPTO_ETL_DIARIO');
END;
/


" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">-- 1. Está presente? Quando roda?</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> *</span></span>
<span class="line"><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4">   job_admin_all_jobs_v</span></span>
<span class="line"><span style="color: #569CD6">WHERE</span><span style="color: #D4D4D4">  </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&#39;DEMOAPP&#39;</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AND</span><span style="color: #D4D4D4"> job_name = </span><span style="color: #CE9178">&#39;JOB_XPTO_ETL_DIARIO&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">-- 2. Está executando agora? Há quanto tempo?</span></span>
<span class="line"><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> running_instance, elapsed_time</span></span>
<span class="line"><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4">   job_admin_running_v</span></span>
<span class="line"><span style="color: #569CD6">WHERE</span><span style="color: #D4D4D4">  </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&#39;DEMOAPP&#39;</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AND</span><span style="color: #D4D4D4"> job_name = </span><span style="color: #CE9178">&#39;JOB_XPTO_ETL_DIARIO&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">-- 3. Pausar com segurança (parar se ativo, depois desabilitar)</span></span>
<span class="line"><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">  pkg_job_admin.disable_job(</span><span style="color: #CE9178">&#39;DEMOAPP.JOB_XPTO_ETL_DIARIO&#39;</span><span style="color: #D4D4D4">, p_stop_running =&gt; TRUE);</span></span>
<span class="line"><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">/</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">-- 4. Reativar</span></span>
<span class="line"><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">  pkg_job_admin.enable_job(</span><span style="color: #CE9178">&#39;DEMOAPP.JOB_XPTO_ETL_DIARIO&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">/</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"></span></code></pre></div>



<p><br></p>



<p><br><br><br></p>



<p><strong>Qual a serventia dessa solução ? </strong><br><br>Ambientes Oracle costumam conviver com dois mecanismos de agendamento: DBMS_SCHEDULER (moderno) e DBMS_JOB (legado). Quando precisamos inventariar, monitorar, habilitar/desabilitar ou gerenciar em lote ambos os tipos, a experiência comum é assimétrica e dispersa.<br>Este projeto entrega uma interface única e consistente para manipular os dois mundos:</p>



<ul class="wp-block-list">
<li>Visões consolidadas para inventário e execução.</li>



<li>Um pacote PL/SQL com comandos simples e legíveis para operações pontuais e em lote.</li>



<li>Role e sinônimos públicos para padronizar o consumo de forma segura.</li>
</ul>



<p><br></p>



<p><br><br><br><br></p>



<p></p>



<p class="has-medium-font-size"><strong>Abaixo consta o codigo inteiro do pacote pkg_job_admin</strong> </p>



<div class="wp-block-file aligncenter"><a id="wp-block-file--media-5691fc75-8483-4dd2-a032-4fcb5a7fb647" href="https://furushima.com.br/wp-content/uploads/2025/09/job_admin_setup_completo.zip">Download &#8211; script pkg_job_admin &#8211; ORACLE</a><a href="https://furushima.com.br/wp-content/uploads/2025/09/job_admin_setup_completo.zip" class="wp-block-file__button wp-element-button" download aria-describedby="wp-block-file--media-5691fc75-8483-4dd2-a032-4fcb5a7fb647">Baixar</a></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="-- =================================================================================================
--  job_admin_setup_completo.sql
--  Administração unificada de jobs no Oracle Database (DBMS_SCHEDULER e DBMS_JOB)
--  Autor: Carlos Furushima — Furushima IT
--  Direitos Autorais: Este script é propriedade intelectual de Furushima IT. Todos os direitos reservados.
--
--  OBJETIVO
--  --------
--  Fornecer uma interface única, consistente e profissional para:
--    • Inventariar jobs do SCHEDULER e do DBMS_JOB em visões consolidadas;
--    • Consultar jobs em execução (tempo decorrido e sessão, quando aplicável);
--    • Habilitar/Desabilitar jobs individualmente (por nome ou número);
--    • Habilitar/Desabilitar em lote por padrão de nome;
--    • Padronizar o consumo por meio de uma ROLE e sinônimos públicos.
--
--  O QUE É CRIADO
--  --------------
--    Views:
--      - JOB_ADMIN_ALL_JOBS      : inventário unificado (SCHEDULER + DBMS_JOB)
--      - JOB_ADMIN_RUNNING       : execução unificada (SCHEDULER + DBMS_JOB)
--      - JOB_ADMIN_ALL_JOBS_V    : inventário formatado para leitura humana
--      - JOB_ADMIN_RUNNING_V     : execução formatada para leitura humana
--
--    Pacote:
--      - PKG_JOB_ADMIN           : utilitários de listagem e (des)ativação unificada
--
--    Segurança e Acesso:
--      - ROLE JOBDBMSSCHEDULERALL com grants de SELECT/EXECUTE
--      - Sinônimos públicos para facilitar o uso por quem tiver a ROLE
--
--  PRÉ-REQUISITOS
--  --------------
--  • Executar com um usuário com privilégios para consultar dicionários DBA_* e GV$* e criar objetos.
--  • O pacote é AUTHID DEFINER (permissões do dono do pacote). Usuários finais só precisam da ROLE.
--
--  USO TÍPICO
--  ----------
--  -- Inventário:
--  BEGIN
--    pkg_job_admin.list_jobs;                       -- tudo
--    pkg_job_admin.list_jobs('DEMOAPP');            -- por owner
--    pkg_job_admin.list_jobs(p_like =&gt; 'JOB_%');    -- por padrão (LIKE)
--  END;
--  /
--
--  -- Executando agora:
--  BEGIN
--    pkg_job_admin.list_running_jobs;                       -- tudo
--    pkg_job_admin.list_running_jobs('DEMOAPP');            -- por owner
--    pkg_job_admin.list_running_jobs(p_like =&gt; 'SYNC_%');   -- por padrão (LIKE)
--  END;
--  /
--
--  -- Operações pontuais:
--  -- SCHEDULER (identificador por nome, owner opcional se único no banco)
--  -- BEGIN
--  --   pkg_job_admin.disable_job('DEMOAPP.JOB_ATUALIZA_INDICES', p_stop_running =&gt; TRUE);
--  --   pkg_job_admin.enable_job ('DEMOAPP.JOB_ATUALIZA_INDICES');
--  -- END;
--  -- /
--  --
--  -- DBMS_JOB (identificador numérico; owner opcional apenas para validar pertinência)
--  -- BEGIN
--  --   pkg_job_admin.disable_job('128', p_owner =&gt; 'SYS', p_stop_running =&gt; TRUE);
--  --   pkg_job_admin.enable_job ('128', p_owner =&gt; 'SYS');
--  -- END;
--  -- /
--
--  -- Lote por padrão (por tipo):
--  -- BEGIN
--  --   pkg_job_admin.set_jobs_by_pattern(
--  --     p_name_like    =&gt; 'JOB_SYNC_%',
--  --     p_enable       =&gt; FALSE,                               -- desativar
--  --     p_owner        =&gt; 'DEMOAPP',                           -- opcional
--  --     p_type         =&gt; pkg_job_admin.c_type_scheduler,      -- SCHEDULER | DBMS_JOB | ANY
--  --     p_stop_running =&gt; TRUE
--  --   );
--  -- END;
--  -- /
--
--  DICAS
--  -----
--  • O script é idempotente (CREATE OR REPLACE; checagens seguras). Pode ser executado mais de uma vez.
--  • Saída “limpa”: mensagens organizadas por PROMPT/DBMS_OUTPUT para auditoria e documentação.
-- =================================================================================================

SET FEEDBACK ON
SET SERVEROUTPUT ON SIZE UNLIMITED
SET VERIFY OFF

PROMPT
PROMPT ═════════════════════════════════════════════════════════════════════════════════════════════
PROMPT   Iniciando job_admin_setup_completo.sql
PROMPT ═════════════════════════════════════════════════════════════════════════════════════════════

-- -----------------------------------------------------------------------------------------------
-- 0) CONTEXTO — Mostra o usuário (owner) sob o qual os objetos serão criados
-- -----------------------------------------------------------------------------------------------
DECLARE
  l_user VARCHAR2(128) := USER;
BEGIN
  DBMS_OUTPUT.PUT_LINE('Owner atual: '||l_user);
END;
/

PROMPT
PROMPT ── 1) Criando/Atualizando Views Consolidadas …

-- ===============================================================================================
-- 1.1) JOB_ADMIN_ALL_JOBS
--      Consolida em uma única visão os jobs do DBMS_SCHEDULER e do DBMS_JOB.
--      Observações de tipos:
--        • next_run_date / last_start_date: TIMESTAMP WITH TIME ZONE (SCHEDULER) x DATE (DBMS_JOB)
--          -&gt; o Oracle promove DATE para TIMESTAMP durante o UNION ALL (sem perda de funcionalidade).
--        • last_run_duration: INTERVAL no SCHEDULER; CAST de NULL para INTERVAL no DBMS_JOB.
--        • job_action / repeat_interval: normalizados para VARCHAR2 (até 4000) no DBMS_JOB.
-- ===============================================================================================
CREATE OR REPLACE VIEW job_admin_all_jobs AS
    SELECT owner,
           job_name,
           'SCHEDULER'               AS job_type,
           CASE WHEN enabled = 'TRUE' THEN 'TRUE' ELSE 'FALSE' END AS enabled,
           state,
           next_run_date,                                -- TIMESTAMP WITH TIME ZONE
           last_start_date,                              -- TIMESTAMP WITH TIME ZONE
           last_run_duration,                            -- INTERVAL DAY TO SECOND
           job_action,                                   -- VARCHAR2/CLOB (na maioria dos casos, até 4000)
           repeat_interval                               -- VARCHAR2
      FROM dba_scheduler_jobs
  UNION ALL
    SELECT schema_user                                   AS owner,
           TO_CHAR(job)                                  AS job_name,
           'DBMS_JOB'                                    AS job_type,
           CASE broken WHEN 'Y' THEN 'FALSE' ELSE 'TRUE' END AS enabled,
           CAST(NULL AS VARCHAR2(30))                    AS state,
           next_date,                                    -- DATE (promovido a TIMESTAMP no UNION)
           last_date                                     AS last_start_date, -- DATE
           CAST(NULL AS INTERVAL DAY TO SECOND)          AS last_run_duration,
           SUBSTR(what,     4000)                        AS job_action,      -- LONG -&gt; VARCHAR2
           SUBSTR(interval, 4000)                        AS repeat_interval  -- LONG -&gt; VARCHAR2
      FROM dba_jobs
;

-- ===============================================================================================
-- 1.2) JOB_ADMIN_RUNNING
--      Consolida os jobs em execução. Para DBMS_JOB, calcula elapsed pelo logon_time da sessão.
--      Observações:
--        • cpu_used não se aplica ao DBMS_JOB; representa-se com NULL (cast para INTERVAL).
-- ===============================================================================================
CREATE OR REPLACE VIEW job_admin_running AS
    SELECT owner,
           job_name,
           'SCHEDULER'               AS job_type,
           session_id,
           running_instance,
           elapsed_time,                                 -- INTERVAL
           cpu_used                                      -- INTERVAL
      FROM dba_scheduler_running_jobs
  UNION ALL
    SELECT j.schema_user           AS owner,
           TO_CHAR(r.job)          AS job_name,
           'DBMS_JOB'              AS job_type,
           r.sid                   AS session_id,
           s.inst_id               AS running_instance,
           NUMTODSINTERVAL(TRUNC((SYSDATE - s.logon_time)*86400),'SECOND') AS elapsed_time,
           CAST(NULL AS INTERVAL DAY TO SECOND)          AS cpu_used
      FROM dba_jobs_running r
      JOIN gv$session s ON s.sid = r.sid
      JOIN dba_jobs j   ON j.job = r.job
;

-- ===============================================================================================
-- 1.3) JOB_ADMIN_ALL_JOBS_V — Versão “amigável” (formatos para leitura humana)
-- ===============================================================================================
CREATE OR REPLACE VIEW job_admin_all_jobs_v AS
SELECT owner, job_name, job_type, enabled, state,
       TO_CHAR(next_run_date,'YYYY-MM-DD HH24:MI:SS')      AS next_run_date,
       TO_CHAR(last_start_date,'YYYY-MM-DD HH24:MI:SS')    AS last_start_date,
       CASE WHEN last_run_duration IS NULL THEN '-' ELSE
         EXTRACT(DAY FROM last_run_duration)||' '||
         LPAD(EXTRACT(HOUR FROM last_run_duration),2,'0')||':'||
         LPAD(EXTRACT(MINUTE FROM last_run_duration),2,'0')||':'||
         LPAD(TRUNC(EXTRACT(SECOND FROM last_run_duration)),2,'0')
       END AS last_run_duration,
       job_action, repeat_interval
  FROM job_admin_all_jobs
;

-- ===============================================================================================
-- 1.4) JOB_ADMIN_RUNNING_V — Versão “amigável” (formatos para leitura humana)
-- ===============================================================================================
CREATE OR REPLACE VIEW job_admin_running_v AS
SELECT owner, job_name, job_type, session_id, running_instance,
       CASE WHEN elapsed_time IS NULL THEN '-' ELSE
         EXTRACT(DAY FROM elapsed_time)||' '||
         LPAD(EXTRACT(HOUR FROM elapsed_time),2,'0')||':'||
         LPAD(EXTRACT(MINUTE FROM elapsed_time),2,'0')||':'||
         LPAD(TRUNC(EXTRACT(SECOND FROM elapsed_time)),2,'0')
       END AS elapsed_time,
       CASE WHEN cpu_used IS NULL THEN '-' ELSE
         EXTRACT(DAY FROM cpu_used)||' '||
         LPAD(EXTRACT(HOUR FROM cpu_used),2,'0')||':'||
         LPAD(EXTRACT(MINUTE FROM cpu_used),2,'0')||':'||
         LPAD(TRUNC(EXTRACT(SECOND FROM cpu_used)),2,'0')
       END AS cpu_used
  FROM job_admin_running
;

PROMPT ✓ Views criadas/atualizadas com sucesso.

PROMPT
PROMPT ── 2) Criando/Atualizando Pacote (SPEC) …

-- =================================================================================================
-- 2) ESPECIFICAÇÃO DO PACOTE — PKG_JOB_ADMIN
--    Contém constantes de tipo e procedimentos públicos de listagem e (des)ativação unificada.
-- =================================================================================================
CREATE OR REPLACE PACKAGE pkg_job_admin AUTHID DEFINER AS
  -- Constantes para filtro por tipo
  c_type_scheduler CONSTANT VARCHAR2(11) := 'SCHEDULER';
  c_type_dbms_job  CONSTANT VARCHAR2(8)  := 'DBMS_JOB';
  c_type_any       CONSTANT VARCHAR2(3)  := 'ANY';

  -- Listagem de jobs (inventário)
  PROCEDURE list_jobs(
    p_owner IN VARCHAR2 DEFAULT NULL,   -- filtra por owner
    p_like  IN VARCHAR2 DEFAULT NULL    -- filtra por padrão (LIKE)
  );

  -- Listagem de jobs em execução
  PROCEDURE list_running_jobs(
    p_owner IN VARCHAR2 DEFAULT NULL,   -- filtra por owner
    p_like  IN VARCHAR2 DEFAULT NULL    -- filtra por padrão (LIKE)
  );

  -- Habilita/Desabilita um job (identificador por nome SCHEDULER ou número DBMS_JOB)
  PROCEDURE set_job_enabled(
    p_job_identifier IN VARCHAR2,       -- 'OWNER.JOB_NAME' | 'JOB_NAME' | '123' (DBMS_JOB)
    p_enable         IN BOOLEAN,        -- TRUE = ENABLE; FALSE = DISABLE
    p_owner          IN VARCHAR2 DEFAULT NULL,  -- para SCHEDULER sem owner único ou DBMS_JOB para validar owner
    p_stop_running   IN BOOLEAN DEFAULT FALSE   -- encerra execução corrente (se houver)
  );

  -- Açúcares sintáticos (conveniências)
  PROCEDURE enable_job(
    p_job_identifier IN VARCHAR2,
    p_owner          IN VARCHAR2 DEFAULT NULL,
    p_stop_running   IN BOOLEAN DEFAULT FALSE
  );

  PROCEDURE disable_job(
    p_job_identifier IN VARCHAR2,
    p_owner          IN VARCHAR2 DEFAULT NULL,
    p_stop_running   IN BOOLEAN DEFAULT TRUE
  );

  -- Habilita/Desabilita em lote por padrão de nome e tipo
  PROCEDURE set_jobs_by_pattern(
    p_name_like     IN VARCHAR2,                      -- ex: 'JOB_SYNC_%'
    p_enable        IN BOOLEAN,                       -- TRUE/FALSE
    p_owner         IN VARCHAR2 DEFAULT NULL,         -- opcional
    p_type          IN VARCHAR2 DEFAULT c_type_any,   -- SCHEDULER | DBMS_JOB | ANY
    p_stop_running  IN BOOLEAN DEFAULT FALSE
  );
END pkg_job_admin;
/
SHOW ERRORS

PROMPT
PROMPT ── 3) Criando/Atualizando Pacote (BODY) …

-- =================================================================================================
-- 3) CORPO DO PACOTE — PKG_JOB_ADMIN
--    Implementa utilitários de formatação, detecção de owner/instância, e operações de controle.
-- =================================================================================================
CREATE OR REPLACE PACKAGE BODY pkg_job_admin AS

  -- ---------------------------------------------------------------------------------------------
  -- Função auxiliar: formata INTERVAL DAY TO SECOND em 'DD HH24:MI:SS'
  -- ---------------------------------------------------------------------------------------------
  FUNCTION fmt_ds(p INTERVAL DAY TO SECOND) RETURN VARCHAR2 IS
    l_day  PLS_INTEGER; l_hour PLS_INTEGER; l_min PLS_INTEGER; l_sec PLS_INTEGER;
  BEGIN
    IF p IS NULL THEN RETURN '-'; END IF;
    l_day  := EXTRACT(DAY    FROM p);
    l_hour := EXTRACT(HOUR   FROM p);
    l_min  := EXTRACT(MINUTE FROM p);
    l_sec  := TRUNC(EXTRACT(SECOND FROM p));
    RETURN LPAD(l_day,2,'0')||' '||LPAD(l_hour,2,'0')||':'||LPAD(l_min,2,'0')||':'||LPAD(l_sec,2,'0');
  END fmt_ds;

  -- ---------------------------------------------------------------------------------------------
  -- Função auxiliar: TO_CHAR seguro para datas que podem ser NULL (retorna '-' no NULL)
  -- ---------------------------------------------------------------------------------------------
  FUNCTION to_char_nvl(p_date DATE) RETURN VARCHAR2 IS
  BEGIN
    RETURN CASE WHEN p_date IS NULL THEN '-' ELSE TO_CHAR(p_date,'YYYY-MM-DD HH24:MI:SS') END;
  END;

  -- ---------------------------------------------------------------------------------------------
  -- Monta o nome totalmente qualificado do job de SCHEDULER
  -- ---------------------------------------------------------------------------------------------
  FUNCTION sched_job_fqname(p_owner IN VARCHAR2, p_job_name IN VARCHAR2) RETURN VARCHAR2 IS
  BEGIN
    RETURN CASE WHEN p_owner IS NOT NULL THEN UPPER(p_owner)||'.'||UPPER(p_job_name) ELSE UPPER(p_job_name) END;
  END;

  -- ---------------------------------------------------------------------------------------------
  -- Solicita parada de job SCHEDULER, se estiver em execução (silencioso em falhas)
  -- ---------------------------------------------------------------------------------------------
  PROCEDURE stop_scheduler_if_running(p_owner IN VARCHAR2, p_job_name IN VARCHAR2) IS
    l_fq VARCHAR2(261) := sched_job_fqname(p_owner, p_job_name);
  BEGIN
    DBMS_SCHEDULER.STOP_JOB(job_name =&gt; l_fq, force =&gt; TRUE);
  EXCEPTION
    WHEN OTHERS THEN NULL;
  END;

  -- ---------------------------------------------------------------------------------------------
  -- Encerra sessão de DBMS_JOB, se houver (suporte RAC com @inst_id)
  -- ---------------------------------------------------------------------------------------------
  PROCEDURE kill_dbms_job_session(p_job_id IN NUMBER) IS
    l_sid     NUMBER;
    l_serial  NUMBER;
    l_inst    NUMBER;
    l_stmt    VARCHAR2(200);
  BEGIN
    SELECT s.sid, s.serial#, s.inst_id
      INTO l_sid, l_serial, l_inst
      FROM dba_jobs_running r
      JOIN gv$session s ON s.sid = r.sid
     WHERE r.job = p_job_id
       AND ROWNUM = 1;

    l_stmt := 'ALTER SYSTEM KILL SESSION '''||l_sid||','||l_serial||
              CASE WHEN l_inst IS NOT NULL THEN ',@'||l_inst ELSE NULL END||''' IMMEDIATE';
    EXECUTE IMMEDIATE l_stmt;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN NULL;
    WHEN OTHERS THEN NULL;
  END;

  -- ---------------------------------------------------------------------------------------------
  -- Resolve owner de job SCHEDULER quando usuário não informou p_owner
  -- Lança erro se não encontrado ou se existir em múltiplos owners.
  -- ---------------------------------------------------------------------------------------------
  PROCEDURE resolve_scheduler(p_owner IN VARCHAR2, p_job_name IN VARCHAR2,
                              o_owner OUT VARCHAR2, o_job_name OUT VARCHAR2) IS
    l_cnt INTEGER;
  BEGIN
    o_job_name := UPPER(p_job_name);
    IF p_owner IS NOT NULL THEN o_owner := UPPER(p_owner); RETURN; END IF;

    SELECT COUNT(DISTINCT owner) INTO l_cnt
      FROM dba_scheduler_jobs
     WHERE job_name = o_job_name;

    IF l_cnt = 0 THEN
      RAISE NO_DATA_FOUND;
    ELSIF l_cnt &gt; 1 THEN
      RAISE_APPLICATION_ERROR(-20002,
        'JOB_NAME existe em múltiplos owners. Informe p_owner. JOB_NAME='||o_job_name);
    ELSE
      SELECT owner INTO o_owner
        FROM dba_scheduler_jobs
       WHERE job_name = o_job_name
         AND ROWNUM = 1;
    END IF;
  END resolve_scheduler;

  -- ---------------------------------------------------------------------------------------------
  -- Listagem: inventário unificado
  -- ---------------------------------------------------------------------------------------------
  PROCEDURE list_jobs(p_owner IN VARCHAR2 DEFAULT NULL, p_like IN VARCHAR2 DEFAULT NULL) IS
  BEGIN
    DBMS_OUTPUT.PUT_LINE('=== JOBS (SCHEDULER) ===');
    FOR r IN (
      SELECT owner, job_name, enabled, state, next_run_date, job_action
        FROM dba_scheduler_jobs
       WHERE (p_owner IS NULL OR owner = UPPER(p_owner))
         AND (p_like  IS NULL OR job_name LIKE UPPER(p_like))
       ORDER BY owner, job_name
    ) LOOP
      DBMS_OUTPUT.PUT_LINE(r.owner||'.'||r.job_name||
                           ' | enabled='||r.enabled||
                           ' | state='||NVL(r.state,'-')||
                           ' | next='||to_char_nvl(CAST(r.next_run_date AS DATE))||
                           ' | action='||SUBSTR(r.job_action,1,60));
    END LOOP;

    DBMS_OUTPUT.PUT_LINE(CHR(10)||'=== JOBS (DBMS_JOB) ===');
    FOR r IN (
      SELECT schema_user AS owner, job AS job_id, DECODE(broken,'Y','FALSE','TRUE') AS enabled,
             next_date, what
        FROM dba_jobs
       WHERE (p_owner IS NULL OR schema_user = UPPER(p_owner))
         AND (p_like  IS NULL OR TO_CHAR(job) LIKE p_like OR UPPER(what) LIKE UPPER(p_like))
       ORDER BY schema_user, job
    ) LOOP
      DBMS_OUTPUT.PUT_LINE(r.owner||'.'||r.job_id||
                           ' | enabled='||r.enabled||
                           ' | next='||to_char_nvl(r.next_date)||
                           ' | what='||SUBSTR(r.what,1,60));
    END LOOP;
  END list_jobs;

  -- ---------------------------------------------------------------------------------------------
  -- Listagem: execução unificada
  -- ---------------------------------------------------------------------------------------------
  PROCEDURE list_running_jobs(p_owner IN VARCHAR2 DEFAULT NULL, p_like IN VARCHAR2 DEFAULT NULL) IS
  BEGIN
    DBMS_OUTPUT.PUT_LINE('=== RUNNING (SCHEDULER) ===');
    FOR r IN (
      SELECT owner, job_name, session_id, running_instance, elapsed_time, cpu_used
        FROM dba_scheduler_running_jobs
       WHERE (p_owner IS NULL OR owner = UPPER(p_owner))
         AND (p_like  IS NULL OR job_name LIKE UPPER(p_like))
       ORDER BY running_instance, job_name
    ) LOOP
      DBMS_OUTPUT.PUT_LINE(r.owner||'.'||r.job_name||
                           ' | sid='||r.session_id||
                           ' | inst='||r.running_instance||
                           ' | elapsed='||fmt_ds(r.elapsed_time)||
                           ' | cpu='||fmt_ds(r.cpu_used));
    END LOOP;

    DBMS_OUTPUT.PUT_LINE(CHR(10)||'=== RUNNING (DBMS_JOB) ===');
    FOR r IN (
      SELECT j.schema_user AS owner, r.job AS job_id, s.sid, s.serial#,
             s.inst_id AS running_instance,
             NUMTODSINTERVAL(TRUNC((SYSDATE - s.logon_time)*86400),'SECOND') AS elapsed_time,
             j.what
        FROM dba_jobs_running r
        JOIN gv$session s ON s.sid = r.sid
        JOIN dba_jobs j   ON j.job = r.job
       WHERE (p_owner IS NULL OR j.schema_user = UPPER(p_owner))
         AND (p_like  IS NULL OR TO_CHAR(r.job) LIKE p_like OR UPPER(j.what) LIKE UPPER(p_like))
       ORDER BY running_instance, job_id
    ) LOOP
      DBMS_OUTPUT.PUT_LINE(r.owner||'.'||r.job_id||
                           ' | sid='||r.sid||','||r.serial#||
                           ' | inst='||r.running_instance||
                           ' | elapsed='||fmt_ds(r.elapsed_time));
    END LOOP;
  END list_running_jobs;

  -- ---------------------------------------------------------------------------------------------
  -- Núcleo: habilita/desabilita por identificador (nome SCHEDULER ou número DBMS_JOB)
  -- ---------------------------------------------------------------------------------------------
  PROCEDURE set_job_enabled(
    p_job_identifier IN VARCHAR2,
    p_enable         IN BOOLEAN,
    p_owner          IN VARCHAR2 DEFAULT NULL,
    p_stop_running   IN BOOLEAN DEFAULT FALSE
  ) IS
    l_owner    VARCHAR2(128);
    l_job_name VARCHAR2(128);
    l_job_id   NUMBER;
  BEGIN
    -- 1) Tentar SCHEDULER (nome)
    BEGIN
      IF REGEXP_LIKE(p_job_identifier,'^\d+$') THEN RAISE NO_DATA_FOUND; END IF;

      IF INSTR(p_job_identifier,'.') &gt; 0 THEN
        l_owner    := UPPER(REGEXP_SUBSTR(p_job_identifier,'^([^\.]+)'));
        l_job_name := UPPER(REGEXP_SUBSTR(p_job_identifier,'\.([^\.]+)$',1,1,NULL,1));
      ELSE
        l_job_name := UPPER(p_job_identifier);
        resolve_scheduler(p_owner, l_job_name, l_owner, l_job_name);
      END IF;

      -- valida existência
      DECLARE l_dummy PLS_INTEGER;
      BEGIN
        SELECT 1 INTO l_dummy
          FROM dba_scheduler_jobs
         WHERE owner = l_owner AND job_name = l_job_name AND ROWNUM = 1;
      END;

      IF p_stop_running THEN
        stop_scheduler_if_running(l_owner, l_job_name);
      END IF;

      IF p_enable THEN
        DBMS_SCHEDULER.ENABLE( sched_job_fqname(l_owner, l_job_name) );
      ELSE
        DBMS_SCHEDULER.DISABLE( sched_job_fqname(l_owner, l_job_name) );
      END IF;

      DBMS_OUTPUT.PUT_LINE('OK (SCHEDULER) '||
        sched_job_fqname(l_owner,l_job_name)||' =&gt; '||
        CASE WHEN p_enable THEN 'ENABLED' ELSE 'DISABLED' END);

      RETURN;
    EXCEPTION
      WHEN NO_DATA_FOUND THEN NULL; -- não era scheduler; tentar DBMS_JOB
    END;

    -- 2) Tentar DBMS_JOB (número)
    BEGIN
      l_job_id := TO_NUMBER(TRIM(p_job_identifier));

      -- valida existência (restringe owner se informado)
      DECLARE l_dummy2 PLS_INTEGER;
      BEGIN
        SELECT 1 INTO l_dummy2
          FROM dba_jobs
         WHERE job = l_job_id
           AND (p_owner IS NULL OR schema_user = UPPER(p_owner))
           AND ROWNUM = 1;
      END;

      IF p_stop_running THEN
        kill_dbms_job_session(l_job_id);
      END IF;

      DBMS_JOB.BROKEN(l_job_id, NOT p_enable);

      DBMS_OUTPUT.PUT_LINE('OK (DBMS_JOB) '||l_job_id||' =&gt; '||
        CASE WHEN p_enable THEN 'ENABLED' ELSE 'DISABLED' END);

      RETURN;
    EXCEPTION
      WHEN VALUE_ERROR    THEN NULL;
      WHEN INVALID_NUMBER THEN NULL;
      WHEN NO_DATA_FOUND  THEN NULL;
    END;

    -- 3) Não encontrado em nenhuma modalidade
    RAISE_APPLICATION_ERROR(-20001,
      'Job não encontrado como SCHEDULER (por nome) nem DBMS_JOB (por número): '||p_job_identifier);
  END set_job_enabled;

  -- Açúcares sintáticos
  PROCEDURE enable_job(
    p_job_identifier IN VARCHAR2,
    p_owner          IN VARCHAR2 DEFAULT NULL,
    p_stop_running   IN BOOLEAN  DEFAULT FALSE
  ) IS
  BEGIN
    set_job_enabled(p_job_identifier =&gt; p_job_identifier,
                    p_enable         =&gt; TRUE,
                    p_owner          =&gt; p_owner,
                    p_stop_running   =&gt; p_stop_running);
  END;

  PROCEDURE disable_job(
    p_job_identifier IN VARCHAR2,
    p_owner          IN VARCHAR2 DEFAULT NULL,
    p_stop_running   IN BOOLEAN  DEFAULT TRUE
  ) IS
  BEGIN
    set_job_enabled(p_job_identifier =&gt; p_job_identifier,
                    p_enable         =&gt; FALSE,
                    p_owner          =&gt; p_owner,
                    p_stop_running   =&gt; p_stop_running);
  END;

  -- ---------------------------------------------------------------------------------------------
  -- Habilita/Desabilita em lote por padrão (LIKE) e, opcionalmente, por tipo
  -- ---------------------------------------------------------------------------------------------
  PROCEDURE set_jobs_by_pattern(
    p_name_like     IN VARCHAR2,
    p_enable        IN BOOLEAN,
    p_owner         IN VARCHAR2 DEFAULT NULL,
    p_type          IN VARCHAR2 DEFAULT c_type_any,
    p_stop_running  IN BOOLEAN  DEFAULT FALSE
  ) IS
  BEGIN
    -- SCHEDULER
    IF UPPER(p_type) IN (c_type_any, c_type_scheduler) THEN
      FOR r IN (
        SELECT owner, job_name
          FROM dba_scheduler_jobs
         WHERE (p_owner IS NULL OR owner = UPPER(p_owner))
           AND job_name LIKE UPPER(p_name_like)
      ) LOOP
        set_job_enabled(r.owner||'.'||r.job_name, p_enable, NULL, p_stop_running);
      END LOOP;
    END IF;

    -- DBMS_JOB
    IF UPPER(p_type) IN (c_type_any, c_type_dbms_job) THEN
      FOR r IN (
        SELECT schema_user AS owner, job
          FROM dba_jobs
         WHERE (p_owner IS NULL OR schema_user = UPPER(p_owner))
           AND (TO_CHAR(job) LIKE p_name_like OR UPPER(what) LIKE UPPER(p_name_like))
      ) LOOP
        set_job_enabled(TO_CHAR(r.job), p_enable, r.owner, p_stop_running);
      END LOOP;
    END IF;
  END set_jobs_by_pattern;

END pkg_job_admin;
/
SHOW ERRORS

PROMPT ✓ Pacote criado/atualizado com sucesso.

PROMPT
PROMPT ── 4) Segurança: ROLE, Grants e Sinônimos Públicos …

-- =================================================================================================
-- 4.1) ROLE — criada apenas se não existir
-- =================================================================================================
DECLARE
  l_cnt INTEGER;
BEGIN
  SELECT COUNT(*) INTO l_cnt FROM dba_roles WHERE role = 'JOBDBMSSCHEDULERALL';
  IF l_cnt = 0 THEN
    EXECUTE IMMEDIATE 'CREATE ROLE JOBDBMSSCHEDULERALL';
    DBMS_OUTPUT.PUT_LINE('Role JOBDBMSSCHEDULERALL criada.');
  ELSE
    DBMS_OUTPUT.PUT_LINE('Role JOBDBMSSCHEDULERALL já existente.');
  END IF;
END;
/

-- =================================================================================================
-- 4.2) GRANTS — executar o pacote e consultar as views por meio da ROLE
-- =================================================================================================
GRANT EXECUTE ON pkg_job_admin        TO JOBDBMSSCHEDULERALL;
GRANT SELECT  ON job_admin_all_jobs   TO JOBDBMSSCHEDULERALL;
GRANT SELECT  ON job_admin_running    TO JOBDBMSSCHEDULERALL;
GRANT SELECT  ON job_admin_all_jobs_v TO JOBDBMSSCHEDULERALL;
GRANT SELECT  ON job_admin_running_v  TO JOBDBMSSCHEDULERALL;

-- =================================================================================================
-- 4.3) SINÔNIMOS PÚBLICOS — apontam para os objetos do OWNER atual
--     Observação: garantem uso uniforme via “public synonyms” para quem tiver a ROLE.
-- =================================================================================================
DECLARE
  l_owner VARCHAR2(128) := USER;
BEGIN
  EXECUTE IMMEDIATE 'CREATE OR REPLACE PUBLIC SYNONYM job_admin_all_jobs   FOR '||l_owner||'.job_admin_all_jobs';
  EXECUTE IMMEDIATE 'CREATE OR REPLACE PUBLIC SYNONYM job_admin_running    FOR '||l_owner||'.job_admin_running';
  EXECUTE IMMEDIATE 'CREATE OR REPLACE PUBLIC SYNONYM job_admin_all_jobs_v FOR '||l_owner||'.job_admin_all_jobs_v';
  EXECUTE IMMEDIATE 'CREATE OR REPLACE PUBLIC SYNONYM job_admin_running_v  FOR '||l_owner||'.job_admin_running_v';
  EXECUTE IMMEDIATE 'CREATE OR REPLACE PUBLIC SYNONYM pkg_job_admin        FOR '||l_owner||'.pkg_job_admin';
  DBMS_OUTPUT.PUT_LINE('Sinônimos públicos criados/atualizados.');
END;
/

PROMPT ✓ Segurança configurada (ROLE + grants + sinônimos públicos).

PROMPT
PROMPT ── 5) Auto-Validação (não intrusiva) …

-- =================================================================================================
-- 5.1) Verifica erros de compilação do pacote
-- =================================================================================================
DECLARE
  l_errs INTEGER;
BEGIN
  SELECT COUNT(*) INTO l_errs
    FROM user_errors
   WHERE name = 'PKG_JOB_ADMIN';

  IF l_errs = 0 THEN
    DBMS_OUTPUT.PUT_LINE('Pacote PKG_JOB_ADMIN sem erros de compilação.');
  ELSE
    DBMS_OUTPUT.PUT_LINE('ATENÇÃO: Encontrado(s) '||l_errs||' erro(s) em PKG_JOB_ADMIN:');
    FOR r IN (
      SELECT type, name, line, position, SUBSTR(text,1,200) AS text
        FROM user_errors
       WHERE name = 'PKG_JOB_ADMIN'
       ORDER BY sequence
    ) LOOP
      DBMS_OUTPUT.PUT_LINE(r.type||' '||r.name||' @'||r.line||':'||r.position||' - '||r.text);
    END LOOP;
  END IF;
END;
/

-- =================================================================================================
-- 5.2) Validação simples de acesso às views (sanidade)
-- =================================================================================================
DECLARE
  l_all NUMBER; l_run NUMBER;
BEGIN
  SELECT COUNT(*) INTO l_all FROM job_admin_all_jobs WHERE ROWNUM &lt;= 1;
  SELECT COUNT(*) INTO l_run FROM job_admin_running  WHERE ROWNUM &lt;= 1;
  DBMS_OUTPUT.PUT_LINE('Views acessíveis: JOB_ADMIN_ALL_JOBS e JOB_ADMIN_RUNNING OK.');
END;
/

PROMPT
PROMPT ── 6) Exemplos de Uso (para referência; copiar/colar quando necessário) …

PROMPT
PROMPT -- Inventário:
PROMPT BEGIN
PROMPT   pkg_job_admin.list_jobs;                          -- todos os jobs
PROMPT   pkg_job_admin.list_jobs('DEMOAPP');               -- por owner
PROMPT   pkg_job_admin.list_jobs(p_like =&gt; 'JOB_%');       -- por padrão (LIKE)
PROMPT END;
PROMPT /

PROMPT -- Em execução agora:
PROMPT BEGIN
PROMPT   pkg_job_admin.list_running_jobs;                       -- tudo
PROMPT   pkg_job_admin.list_running_jobs('DEMOAPP');            -- por owner
PROMPT   pkg_job_admin.list_running_jobs(p_like =&gt; 'SYNC_%');   -- por padrão (LIKE)
PROMPT END;
PROMPT /

PROMPT -- Operações pontuais:
PROMPT -- SCHEDULER (por nome; owner opcional se único no banco)
PROMPT -- BEGIN
PROMPT --   pkg_job_admin.disable_job('DEMOAPP.JOB_ATUALIZA_INDICES', p_stop_running =&gt; TRUE);
PROMPT --   pkg_job_admin.enable_job ('DEMOAPP.JOB_ATUALIZA_INDICES');
PROMPT -- END;
PROMPT -- /
PROMPT -- DBMS_JOB (por número; owner apenas para validar pertinência quando desejar)
PROMPT -- BEGIN
PROMPT --   pkg_job_admin.disable_job('128', p_owner =&gt; 'SYS', p_stop_running =&gt; TRUE);
PROMPT --   pkg_job_admin.enable_job ('128', p_owner =&gt; 'SYS');
PROMPT -- END;
PROMPT -- /

PROMPT -- Lote por padrão (por tipo):
PROMPT -- BEGIN
PROMPT --   pkg_job_admin.set_jobs_by_pattern(
PROMPT --     p_name_like    =&gt; 'JOB_SYNC_%',
PROMPT --     p_enable       =&gt; FALSE,
PROMPT --     p_owner        =&gt; 'DEMOAPP',
PROMPT --     p_type         =&gt; pkg_job_admin.c_type_scheduler, -- SCHEDULER | DBMS_JOB | ANY
PROMPT --     p_stop_running =&gt; TRUE
PROMPT --   );
PROMPT -- END;
PROMPT -- /

PROMPT -- Visões consolidadas:
PROMPT -- SELECT * FROM job_admin_all_jobs_v ORDER BY owner, job_type, job_name;
PROMPT -- SELECT * FROM job_admin_running_v  ORDER BY running_instance, job_type, job_name;

PROMPT
PROMPT ═════════════════════════════════════════════════════════════════════════════════════════════
PROMPT   Conclusão: job_admin_setup_completo.sql executado.
PROMPT   Para conceder a ROLE a um usuário final, utilize:
PROMPT     GRANT JOBDBMSSCHEDULERALL TO nome_do_usuario;
PROMPT ═════════════════════════════════════════════════════════════════════════════════════════════
" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">-- =================================================================================================</span></span>
<span class="line"><span style="color: #6A9955">--  job_admin_setup_completo.sql</span></span>
<span class="line"><span style="color: #6A9955">--  Administração unificada de jobs no Oracle Database (DBMS_SCHEDULER e DBMS_JOB)</span></span>
<span class="line"><span style="color: #6A9955">--  Autor: Carlos Furushima — Furushima IT</span></span>
<span class="line"><span style="color: #6A9955">--  Direitos Autorais: Este script é propriedade intelectual de Furushima IT. Todos os direitos reservados.</span></span>
<span class="line"><span style="color: #6A9955">--</span></span>
<span class="line"><span style="color: #6A9955">--  OBJETIVO</span></span>
<span class="line"><span style="color: #6A9955">--  --------</span></span>
<span class="line"><span style="color: #6A9955">--  Fornecer uma interface única, consistente e profissional para:</span></span>
<span class="line"><span style="color: #6A9955">--    • Inventariar jobs do SCHEDULER e do DBMS_JOB em visões consolidadas;</span></span>
<span class="line"><span style="color: #6A9955">--    • Consultar jobs em execução (tempo decorrido e sessão, quando aplicável);</span></span>
<span class="line"><span style="color: #6A9955">--    • Habilitar/Desabilitar jobs individualmente (por nome ou número);</span></span>
<span class="line"><span style="color: #6A9955">--    • Habilitar/Desabilitar em lote por padrão de nome;</span></span>
<span class="line"><span style="color: #6A9955">--    • Padronizar o consumo por meio de uma ROLE e sinônimos públicos.</span></span>
<span class="line"><span style="color: #6A9955">--</span></span>
<span class="line"><span style="color: #6A9955">--  O QUE É CRIADO</span></span>
<span class="line"><span style="color: #6A9955">--  --------------</span></span>
<span class="line"><span style="color: #6A9955">--    Views:</span></span>
<span class="line"><span style="color: #6A9955">--      - JOB_ADMIN_ALL_JOBS      : inventário unificado (SCHEDULER + DBMS_JOB)</span></span>
<span class="line"><span style="color: #6A9955">--      - JOB_ADMIN_RUNNING       : execução unificada (SCHEDULER + DBMS_JOB)</span></span>
<span class="line"><span style="color: #6A9955">--      - JOB_ADMIN_ALL_JOBS_V    : inventário formatado para leitura humana</span></span>
<span class="line"><span style="color: #6A9955">--      - JOB_ADMIN_RUNNING_V     : execução formatada para leitura humana</span></span>
<span class="line"><span style="color: #6A9955">--</span></span>
<span class="line"><span style="color: #6A9955">--    Pacote:</span></span>
<span class="line"><span style="color: #6A9955">--      - PKG_JOB_ADMIN           : utilitários de listagem e (des)ativação unificada</span></span>
<span class="line"><span style="color: #6A9955">--</span></span>
<span class="line"><span style="color: #6A9955">--    Segurança e Acesso:</span></span>
<span class="line"><span style="color: #6A9955">--      - ROLE JOBDBMSSCHEDULERALL com grants de SELECT/EXECUTE</span></span>
<span class="line"><span style="color: #6A9955">--      - Sinônimos públicos para facilitar o uso por quem tiver a ROLE</span></span>
<span class="line"><span style="color: #6A9955">--</span></span>
<span class="line"><span style="color: #6A9955">--  PRÉ-REQUISITOS</span></span>
<span class="line"><span style="color: #6A9955">--  --------------</span></span>
<span class="line"><span style="color: #6A9955">--  • Executar com um usuário com privilégios para consultar dicionários DBA_* e GV$* e criar objetos.</span></span>
<span class="line"><span style="color: #6A9955">--  • O pacote é AUTHID DEFINER (permissões do dono do pacote). Usuários finais só precisam da ROLE.</span></span>
<span class="line"><span style="color: #6A9955">--</span></span>
<span class="line"><span style="color: #6A9955">--  USO TÍPICO</span></span>
<span class="line"><span style="color: #6A9955">--  ----------</span></span>
<span class="line"><span style="color: #6A9955">--  -- Inventário:</span></span>
<span class="line"><span style="color: #6A9955">--  BEGIN</span></span>
<span class="line"><span style="color: #6A9955">--    pkg_job_admin.list_jobs;                       -- tudo</span></span>
<span class="line"><span style="color: #6A9955">--    pkg_job_admin.list_jobs(&#39;DEMOAPP&#39;);            -- por owner</span></span>
<span class="line"><span style="color: #6A9955">--    pkg_job_admin.list_jobs(p_like =&gt; &#39;JOB_%&#39;);    -- por padrão (LIKE)</span></span>
<span class="line"><span style="color: #6A9955">--  END;</span></span>
<span class="line"><span style="color: #6A9955">--  /</span></span>
<span class="line"><span style="color: #6A9955">--</span></span>
<span class="line"><span style="color: #6A9955">--  -- Executando agora:</span></span>
<span class="line"><span style="color: #6A9955">--  BEGIN</span></span>
<span class="line"><span style="color: #6A9955">--    pkg_job_admin.list_running_jobs;                       -- tudo</span></span>
<span class="line"><span style="color: #6A9955">--    pkg_job_admin.list_running_jobs(&#39;DEMOAPP&#39;);            -- por owner</span></span>
<span class="line"><span style="color: #6A9955">--    pkg_job_admin.list_running_jobs(p_like =&gt; &#39;SYNC_%&#39;);   -- por padrão (LIKE)</span></span>
<span class="line"><span style="color: #6A9955">--  END;</span></span>
<span class="line"><span style="color: #6A9955">--  /</span></span>
<span class="line"><span style="color: #6A9955">--</span></span>
<span class="line"><span style="color: #6A9955">--  -- Operações pontuais:</span></span>
<span class="line"><span style="color: #6A9955">--  -- SCHEDULER (identificador por nome, owner opcional se único no banco)</span></span>
<span class="line"><span style="color: #6A9955">--  -- BEGIN</span></span>
<span class="line"><span style="color: #6A9955">--  --   pkg_job_admin.disable_job(&#39;DEMOAPP.JOB_ATUALIZA_INDICES&#39;, p_stop_running =&gt; TRUE);</span></span>
<span class="line"><span style="color: #6A9955">--  --   pkg_job_admin.enable_job (&#39;DEMOAPP.JOB_ATUALIZA_INDICES&#39;);</span></span>
<span class="line"><span style="color: #6A9955">--  -- END;</span></span>
<span class="line"><span style="color: #6A9955">--  -- /</span></span>
<span class="line"><span style="color: #6A9955">--  --</span></span>
<span class="line"><span style="color: #6A9955">--  -- DBMS_JOB (identificador numérico; owner opcional apenas para validar pertinência)</span></span>
<span class="line"><span style="color: #6A9955">--  -- BEGIN</span></span>
<span class="line"><span style="color: #6A9955">--  --   pkg_job_admin.disable_job(&#39;128&#39;, p_owner =&gt; &#39;SYS&#39;, p_stop_running =&gt; TRUE);</span></span>
<span class="line"><span style="color: #6A9955">--  --   pkg_job_admin.enable_job (&#39;128&#39;, p_owner =&gt; &#39;SYS&#39;);</span></span>
<span class="line"><span style="color: #6A9955">--  -- END;</span></span>
<span class="line"><span style="color: #6A9955">--  -- /</span></span>
<span class="line"><span style="color: #6A9955">--</span></span>
<span class="line"><span style="color: #6A9955">--  -- Lote por padrão (por tipo):</span></span>
<span class="line"><span style="color: #6A9955">--  -- BEGIN</span></span>
<span class="line"><span style="color: #6A9955">--  --   pkg_job_admin.set_jobs_by_pattern(</span></span>
<span class="line"><span style="color: #6A9955">--  --     p_name_like    =&gt; &#39;JOB_SYNC_%&#39;,</span></span>
<span class="line"><span style="color: #6A9955">--  --     p_enable       =&gt; FALSE,                               -- desativar</span></span>
<span class="line"><span style="color: #6A9955">--  --     p_owner        =&gt; &#39;DEMOAPP&#39;,                           -- opcional</span></span>
<span class="line"><span style="color: #6A9955">--  --     p_type         =&gt; pkg_job_admin.c_type_scheduler,      -- SCHEDULER | DBMS_JOB | ANY</span></span>
<span class="line"><span style="color: #6A9955">--  --     p_stop_running =&gt; TRUE</span></span>
<span class="line"><span style="color: #6A9955">--  --   );</span></span>
<span class="line"><span style="color: #6A9955">--  -- END;</span></span>
<span class="line"><span style="color: #6A9955">--  -- /</span></span>
<span class="line"><span style="color: #6A9955">--</span></span>
<span class="line"><span style="color: #6A9955">--  DICAS</span></span>
<span class="line"><span style="color: #6A9955">--  -----</span></span>
<span class="line"><span style="color: #6A9955">--  • O script é idempotente (CREATE OR REPLACE; checagens seguras). Pode ser executado mais de uma vez.</span></span>
<span class="line"><span style="color: #6A9955">--  • Saída “limpa”: mensagens organizadas por PROMPT/DBMS_OUTPUT para auditoria e documentação.</span></span>
<span class="line"><span style="color: #6A9955">-- =================================================================================================</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">SET</span><span style="color: #D4D4D4"> FEEDBACK </span><span style="color: #569CD6">ON</span></span>
<span class="line"><span style="color: #569CD6">SET</span><span style="color: #D4D4D4"> SERVEROUTPUT </span><span style="color: #569CD6">ON</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">SIZE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">UNLIMITED</span></span>
<span class="line"><span style="color: #569CD6">SET</span><span style="color: #D4D4D4"> VERIFY </span><span style="color: #569CD6">OFF</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">PROMPT</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT ═════════════════════════════════════════════════════════════════════════════════════════════</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT   Iniciando job_admin_setup_completo.sql</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT ═════════════════════════════════════════════════════════════════════════════════════════════</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">-- -----------------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #6A9955">-- 0) CONTEXTO — Mostra o usuário (owner) sob o qual os objetos serão criados</span></span>
<span class="line"><span style="color: #6A9955">-- -----------------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #569CD6">DECLARE</span></span>
<span class="line"><span style="color: #D4D4D4">  l_user </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">128</span><span style="color: #D4D4D4">) := USER;</span></span>
<span class="line"><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">  DBMS_OUTPUT.PUT_LINE(</span><span style="color: #CE9178">&#39;Owner atual: &#39;</span><span style="color: #D4D4D4">||l_user);</span></span>
<span class="line"><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">/</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">PROMPT</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT ── </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">) Criando/Atualizando Views Consolidadas …</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">-- ===============================================================================================</span></span>
<span class="line"><span style="color: #6A9955">-- 1.1) JOB_ADMIN_ALL_JOBS</span></span>
<span class="line"><span style="color: #6A9955">--      Consolida em uma única visão os jobs do DBMS_SCHEDULER e do DBMS_JOB.</span></span>
<span class="line"><span style="color: #6A9955">--      Observações de tipos:</span></span>
<span class="line"><span style="color: #6A9955">--        • next_run_date / last_start_date: TIMESTAMP WITH TIME ZONE (SCHEDULER) x DATE (DBMS_JOB)</span></span>
<span class="line"><span style="color: #6A9955">--          -&gt; o Oracle promove DATE para TIMESTAMP durante o UNION ALL (sem perda de funcionalidade).</span></span>
<span class="line"><span style="color: #6A9955">--        • last_run_duration: INTERVAL no SCHEDULER; CAST de NULL para INTERVAL no DBMS_JOB.</span></span>
<span class="line"><span style="color: #6A9955">--        • job_action / repeat_interval: normalizados para VARCHAR2 (até 4000) no DBMS_JOB.</span></span>
<span class="line"><span style="color: #6A9955">-- ===============================================================================================</span></span>
<span class="line"><span style="color: #569CD6">CREATE OR REPLACE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">job_admin_all_jobs</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AS</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">           job_name,</span></span>
<span class="line"><span style="color: #D4D4D4">           </span><span style="color: #CE9178">&#39;SCHEDULER&#39;</span><span style="color: #D4D4D4">               </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> job_type,</span></span>
<span class="line"><span style="color: #D4D4D4">           </span><span style="color: #569CD6">CASE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">WHEN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">enabled</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&#39;TRUE&#39;</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">THEN</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;TRUE&#39;</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">ELSE</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;FALSE&#39;</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">enabled</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">           </span><span style="color: #569CD6">state</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">           next_run_date,                                </span><span style="color: #6A9955">-- TIMESTAMP WITH TIME ZONE</span></span>
<span class="line"><span style="color: #D4D4D4">           last_start_date,                              </span><span style="color: #6A9955">-- TIMESTAMP WITH TIME ZONE</span></span>
<span class="line"><span style="color: #D4D4D4">           last_run_duration,                            </span><span style="color: #6A9955">-- INTERVAL DAY TO SECOND</span></span>
<span class="line"><span style="color: #D4D4D4">           job_action,                                   </span><span style="color: #6A9955">-- VARCHAR2/CLOB (na maioria dos casos, até 4000)</span></span>
<span class="line"><span style="color: #D4D4D4">           repeat_interval                               </span><span style="color: #6A9955">-- VARCHAR2</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> dba_scheduler_jobs</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">UNION ALL</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> schema_user                                   </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">           TO_CHAR(job)                                  </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> job_name,</span></span>
<span class="line"><span style="color: #D4D4D4">           </span><span style="color: #CE9178">&#39;DBMS_JOB&#39;</span><span style="color: #D4D4D4">                                    </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> job_type,</span></span>
<span class="line"><span style="color: #D4D4D4">           </span><span style="color: #569CD6">CASE</span><span style="color: #D4D4D4"> broken </span><span style="color: #569CD6">WHEN</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;Y&#39;</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">THEN</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;FALSE&#39;</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">ELSE</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;TRUE&#39;</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">enabled</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">           </span><span style="color: #DCDCAA">CAST</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">30</span><span style="color: #D4D4D4">))                    </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">state</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">           next_date,                                    </span><span style="color: #6A9955">-- DATE (promovido a TIMESTAMP no UNION)</span></span>
<span class="line"><span style="color: #D4D4D4">           last_date                                     </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> last_start_date, </span><span style="color: #6A9955">-- DATE</span></span>
<span class="line"><span style="color: #D4D4D4">           </span><span style="color: #DCDCAA">CAST</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> INTERVAL </span><span style="color: #569CD6">DAY</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">TO</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">SECOND</span><span style="color: #D4D4D4">)          </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> last_run_duration,</span></span>
<span class="line"><span style="color: #D4D4D4">           SUBSTR(what,     </span><span style="color: #B5CEA8">4000</span><span style="color: #D4D4D4">)                        </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> job_action,      </span><span style="color: #6A9955">-- LONG -&gt; VARCHAR2</span></span>
<span class="line"><span style="color: #D4D4D4">           SUBSTR(interval, </span><span style="color: #B5CEA8">4000</span><span style="color: #D4D4D4">)                        </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> repeat_interval  </span><span style="color: #6A9955">-- LONG -&gt; VARCHAR2</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> dba_jobs</span></span>
<span class="line"><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">-- ===============================================================================================</span></span>
<span class="line"><span style="color: #6A9955">-- 1.2) JOB_ADMIN_RUNNING</span></span>
<span class="line"><span style="color: #6A9955">--      Consolida os jobs em execução. Para DBMS_JOB, calcula elapsed pelo logon_time da sessão.</span></span>
<span class="line"><span style="color: #6A9955">--      Observações:</span></span>
<span class="line"><span style="color: #6A9955">--        • cpu_used não se aplica ao DBMS_JOB; representa-se com NULL (cast para INTERVAL).</span></span>
<span class="line"><span style="color: #6A9955">-- ===============================================================================================</span></span>
<span class="line"><span style="color: #569CD6">CREATE OR REPLACE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">job_admin_running</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AS</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">           job_name,</span></span>
<span class="line"><span style="color: #D4D4D4">           </span><span style="color: #CE9178">&#39;SCHEDULER&#39;</span><span style="color: #D4D4D4">               </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> job_type,</span></span>
<span class="line"><span style="color: #D4D4D4">           session_id,</span></span>
<span class="line"><span style="color: #D4D4D4">           running_instance,</span></span>
<span class="line"><span style="color: #D4D4D4">           elapsed_time,                                 </span><span style="color: #6A9955">-- INTERVAL</span></span>
<span class="line"><span style="color: #D4D4D4">           cpu_used                                      </span><span style="color: #6A9955">-- INTERVAL</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> dba_scheduler_running_jobs</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">UNION ALL</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> j.schema_user           </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">           TO_CHAR(r.job)          </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> job_name,</span></span>
<span class="line"><span style="color: #D4D4D4">           </span><span style="color: #CE9178">&#39;DBMS_JOB&#39;</span><span style="color: #D4D4D4">              </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> job_type,</span></span>
<span class="line"><span style="color: #D4D4D4">           r.sid                   </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> session_id,</span></span>
<span class="line"><span style="color: #D4D4D4">           s.inst_id               </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> running_instance,</span></span>
<span class="line"><span style="color: #D4D4D4">           NUMTODSINTERVAL(TRUNC((</span><span style="color: #569CD6">SYSDATE</span><span style="color: #D4D4D4"> - s.logon_time)*</span><span style="color: #B5CEA8">86400</span><span style="color: #D4D4D4">),</span><span style="color: #CE9178">&#39;SECOND&#39;</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> elapsed_time,</span></span>
<span class="line"><span style="color: #D4D4D4">           </span><span style="color: #DCDCAA">CAST</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> INTERVAL </span><span style="color: #569CD6">DAY</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">TO</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">SECOND</span><span style="color: #D4D4D4">)          </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> cpu_used</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> dba_jobs_running r</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">JOIN</span><span style="color: #D4D4D4"> gv$</span><span style="color: #569CD6">session</span><span style="color: #D4D4D4"> s </span><span style="color: #569CD6">ON</span><span style="color: #D4D4D4"> s.sid = r.sid</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">JOIN</span><span style="color: #D4D4D4"> dba_jobs j   </span><span style="color: #569CD6">ON</span><span style="color: #D4D4D4"> j.job = r.job</span></span>
<span class="line"><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">-- ===============================================================================================</span></span>
<span class="line"><span style="color: #6A9955">-- 1.3) JOB_ADMIN_ALL_JOBS_V — Versão “amigável” (formatos para leitura humana)</span></span>
<span class="line"><span style="color: #6A9955">-- ===============================================================================================</span></span>
<span class="line"><span style="color: #569CD6">CREATE OR REPLACE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">job_admin_all_jobs_v</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AS</span></span>
<span class="line"><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4">, job_name, job_type, </span><span style="color: #569CD6">enabled</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">state</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">       TO_CHAR(next_run_date,</span><span style="color: #CE9178">&#39;YYYY-MM-DD HH24:MI:SS&#39;</span><span style="color: #D4D4D4">)      </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> next_run_date,</span></span>
<span class="line"><span style="color: #D4D4D4">       TO_CHAR(last_start_date,</span><span style="color: #CE9178">&#39;YYYY-MM-DD HH24:MI:SS&#39;</span><span style="color: #D4D4D4">)    </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> last_start_date,</span></span>
<span class="line"><span style="color: #D4D4D4">       </span><span style="color: #569CD6">CASE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">WHEN</span><span style="color: #D4D4D4"> last_run_duration </span><span style="color: #569CD6">IS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">THEN</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;-&#39;</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">ELSE</span></span>
<span class="line"><span style="color: #D4D4D4">         EXTRACT(</span><span style="color: #569CD6">DAY</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> last_run_duration)||</span><span style="color: #CE9178">&#39; &#39;</span><span style="color: #D4D4D4">||</span></span>
<span class="line"><span style="color: #D4D4D4">         LPAD(EXTRACT(</span><span style="color: #569CD6">HOUR</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> last_run_duration),</span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">,</span><span style="color: #CE9178">&#39;0&#39;</span><span style="color: #D4D4D4">)||</span><span style="color: #CE9178">&#39;:&#39;</span><span style="color: #D4D4D4">||</span></span>
<span class="line"><span style="color: #D4D4D4">         LPAD(EXTRACT(</span><span style="color: #569CD6">MINUTE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> last_run_duration),</span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">,</span><span style="color: #CE9178">&#39;0&#39;</span><span style="color: #D4D4D4">)||</span><span style="color: #CE9178">&#39;:&#39;</span><span style="color: #D4D4D4">||</span></span>
<span class="line"><span style="color: #D4D4D4">         LPAD(TRUNC(EXTRACT(</span><span style="color: #569CD6">SECOND</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> last_run_duration)),</span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">,</span><span style="color: #CE9178">&#39;0&#39;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">       </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> last_run_duration,</span></span>
<span class="line"><span style="color: #D4D4D4">       job_action, repeat_interval</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> job_admin_all_jobs</span></span>
<span class="line"><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">-- ===============================================================================================</span></span>
<span class="line"><span style="color: #6A9955">-- 1.4) JOB_ADMIN_RUNNING_V — Versão “amigável” (formatos para leitura humana)</span></span>
<span class="line"><span style="color: #6A9955">-- ===============================================================================================</span></span>
<span class="line"><span style="color: #569CD6">CREATE OR REPLACE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">job_admin_running_v</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AS</span></span>
<span class="line"><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4">, job_name, job_type, session_id, running_instance,</span></span>
<span class="line"><span style="color: #D4D4D4">       </span><span style="color: #569CD6">CASE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">WHEN</span><span style="color: #D4D4D4"> elapsed_time </span><span style="color: #569CD6">IS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">THEN</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;-&#39;</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">ELSE</span></span>
<span class="line"><span style="color: #D4D4D4">         EXTRACT(</span><span style="color: #569CD6">DAY</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> elapsed_time)||</span><span style="color: #CE9178">&#39; &#39;</span><span style="color: #D4D4D4">||</span></span>
<span class="line"><span style="color: #D4D4D4">         LPAD(EXTRACT(</span><span style="color: #569CD6">HOUR</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> elapsed_time),</span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">,</span><span style="color: #CE9178">&#39;0&#39;</span><span style="color: #D4D4D4">)||</span><span style="color: #CE9178">&#39;:&#39;</span><span style="color: #D4D4D4">||</span></span>
<span class="line"><span style="color: #D4D4D4">         LPAD(EXTRACT(</span><span style="color: #569CD6">MINUTE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> elapsed_time),</span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">,</span><span style="color: #CE9178">&#39;0&#39;</span><span style="color: #D4D4D4">)||</span><span style="color: #CE9178">&#39;:&#39;</span><span style="color: #D4D4D4">||</span></span>
<span class="line"><span style="color: #D4D4D4">         LPAD(TRUNC(EXTRACT(</span><span style="color: #569CD6">SECOND</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> elapsed_time)),</span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">,</span><span style="color: #CE9178">&#39;0&#39;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">       </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> elapsed_time,</span></span>
<span class="line"><span style="color: #D4D4D4">       </span><span style="color: #569CD6">CASE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">WHEN</span><span style="color: #D4D4D4"> cpu_used </span><span style="color: #569CD6">IS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">THEN</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;-&#39;</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">ELSE</span></span>
<span class="line"><span style="color: #D4D4D4">         EXTRACT(</span><span style="color: #569CD6">DAY</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> cpu_used)||</span><span style="color: #CE9178">&#39; &#39;</span><span style="color: #D4D4D4">||</span></span>
<span class="line"><span style="color: #D4D4D4">         LPAD(EXTRACT(</span><span style="color: #569CD6">HOUR</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> cpu_used),</span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">,</span><span style="color: #CE9178">&#39;0&#39;</span><span style="color: #D4D4D4">)||</span><span style="color: #CE9178">&#39;:&#39;</span><span style="color: #D4D4D4">||</span></span>
<span class="line"><span style="color: #D4D4D4">         LPAD(EXTRACT(</span><span style="color: #569CD6">MINUTE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> cpu_used),</span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">,</span><span style="color: #CE9178">&#39;0&#39;</span><span style="color: #D4D4D4">)||</span><span style="color: #CE9178">&#39;:&#39;</span><span style="color: #D4D4D4">||</span></span>
<span class="line"><span style="color: #D4D4D4">         LPAD(TRUNC(EXTRACT(</span><span style="color: #569CD6">SECOND</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> cpu_used)),</span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">,</span><span style="color: #CE9178">&#39;0&#39;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">       </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> cpu_used</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> job_admin_running</span></span>
<span class="line"><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">PROMPT ✓ Views criadas/atualizadas com sucesso.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">PROMPT</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT ── </span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">) Criando/Atualizando Pacote (SPEC) …</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">-- =================================================================================================</span></span>
<span class="line"><span style="color: #6A9955">-- 2) ESPECIFICAÇÃO DO PACOTE — PKG_JOB_ADMIN</span></span>
<span class="line"><span style="color: #6A9955">--    Contém constantes de tipo e procedimentos públicos de listagem e (des)ativação unificada.</span></span>
<span class="line"><span style="color: #6A9955">-- =================================================================================================</span></span>
<span class="line"><span style="color: #569CD6">CREATE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">OR</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">REPLACE</span><span style="color: #D4D4D4"> PACKAGE pkg_job_admin AUTHID DEFINER </span><span style="color: #569CD6">AS</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- Constantes para filtro por tipo</span></span>
<span class="line"><span style="color: #D4D4D4">  c_type_scheduler CONSTANT </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">11</span><span style="color: #D4D4D4">) := </span><span style="color: #CE9178">&#39;SCHEDULER&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  c_type_dbms_job  CONSTANT </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">8</span><span style="color: #D4D4D4">)  := </span><span style="color: #CE9178">&#39;DBMS_JOB&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  c_type_any       CONSTANT </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">3</span><span style="color: #D4D4D4">)  := </span><span style="color: #CE9178">&#39;ANY&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- Listagem de jobs (inventário)</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">PROCEDURE</span><span style="color: #D4D4D4"> list_jobs(</span></span>
<span class="line"><span style="color: #D4D4D4">    p_owner </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4">,   </span><span style="color: #6A9955">-- filtra por owner</span></span>
<span class="line"><span style="color: #D4D4D4">    p_like  </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4">    </span><span style="color: #6A9955">-- filtra por padrão (LIKE)</span></span>
<span class="line"><span style="color: #D4D4D4">  );</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- Listagem de jobs em execução</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">PROCEDURE</span><span style="color: #D4D4D4"> list_running_jobs(</span></span>
<span class="line"><span style="color: #D4D4D4">    p_owner </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4">,   </span><span style="color: #6A9955">-- filtra por owner</span></span>
<span class="line"><span style="color: #D4D4D4">    p_like  </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4">    </span><span style="color: #6A9955">-- filtra por padrão (LIKE)</span></span>
<span class="line"><span style="color: #D4D4D4">  );</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- Habilita/Desabilita um job (identificador por nome SCHEDULER ou número DBMS_JOB)</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">PROCEDURE</span><span style="color: #D4D4D4"> set_job_enabled(</span></span>
<span class="line"><span style="color: #D4D4D4">    p_job_identifier </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">,       </span><span style="color: #6A9955">-- &#39;OWNER.JOB_NAME&#39; | &#39;JOB_NAME&#39; | &#39;123&#39; (DBMS_JOB)</span></span>
<span class="line"><span style="color: #D4D4D4">    p_enable         </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">BOOLEAN</span><span style="color: #D4D4D4">,        </span><span style="color: #6A9955">-- TRUE = ENABLE; FALSE = DISABLE</span></span>
<span class="line"><span style="color: #D4D4D4">    p_owner          </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4">,  </span><span style="color: #6A9955">-- para SCHEDULER sem owner único ou DBMS_JOB para validar owner</span></span>
<span class="line"><span style="color: #D4D4D4">    p_stop_running   </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">BOOLEAN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> FALSE   </span><span style="color: #6A9955">-- encerra execução corrente (se houver)</span></span>
<span class="line"><span style="color: #D4D4D4">  );</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- Açúcares sintáticos (conveniências)</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">PROCEDURE</span><span style="color: #D4D4D4"> enable_job(</span></span>
<span class="line"><span style="color: #D4D4D4">    p_job_identifier </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">    p_owner          </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">    p_stop_running   </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">BOOLEAN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> FALSE</span></span>
<span class="line"><span style="color: #D4D4D4">  );</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">PROCEDURE</span><span style="color: #D4D4D4"> disable_job(</span></span>
<span class="line"><span style="color: #D4D4D4">    p_job_identifier </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">    p_owner          </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">    p_stop_running   </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">BOOLEAN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> TRUE</span></span>
<span class="line"><span style="color: #D4D4D4">  );</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- Habilita/Desabilita em lote por padrão de nome e tipo</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">PROCEDURE</span><span style="color: #D4D4D4"> set_jobs_by_pattern(</span></span>
<span class="line"><span style="color: #D4D4D4">    p_name_like     </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">,                      </span><span style="color: #6A9955">-- ex: &#39;JOB_SYNC_%&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">    p_enable        </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">BOOLEAN</span><span style="color: #D4D4D4">,                       </span><span style="color: #6A9955">-- TRUE/FALSE</span></span>
<span class="line"><span style="color: #D4D4D4">    p_owner         </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4">,         </span><span style="color: #6A9955">-- opcional</span></span>
<span class="line"><span style="color: #D4D4D4">    p_type          </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> c_type_any,   </span><span style="color: #6A9955">-- SCHEDULER | DBMS_JOB | ANY</span></span>
<span class="line"><span style="color: #D4D4D4">    p_stop_running  </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">BOOLEAN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> FALSE</span></span>
<span class="line"><span style="color: #D4D4D4">  );</span></span>
<span class="line"><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> pkg_job_admin;</span></span>
<span class="line"><span style="color: #D4D4D4">/</span></span>
<span class="line"><span style="color: #D4D4D4">SHOW ERRORS</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">PROMPT</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT ── </span><span style="color: #B5CEA8">3</span><span style="color: #D4D4D4">) Criando/Atualizando Pacote (BODY) …</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">-- =================================================================================================</span></span>
<span class="line"><span style="color: #6A9955">-- 3) CORPO DO PACOTE — PKG_JOB_ADMIN</span></span>
<span class="line"><span style="color: #6A9955">--    Implementa utilitários de formatação, detecção de owner/instância, e operações de controle.</span></span>
<span class="line"><span style="color: #6A9955">-- =================================================================================================</span></span>
<span class="line"><span style="color: #569CD6">CREATE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">OR</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">REPLACE</span><span style="color: #D4D4D4"> PACKAGE BODY pkg_job_admin </span><span style="color: #569CD6">AS</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- ---------------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- Função auxiliar: formata INTERVAL DAY TO SECOND em &#39;DD HH24:MI:SS&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- ---------------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">FUNCTION</span><span style="color: #D4D4D4"> fmt_ds(p INTERVAL </span><span style="color: #569CD6">DAY</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">TO</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">SECOND</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">RETURN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">IS</span></span>
<span class="line"><span style="color: #D4D4D4">    l_day  PLS_INTEGER; l_hour PLS_INTEGER; l_min PLS_INTEGER; l_sec PLS_INTEGER;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">IF</span><span style="color: #D4D4D4"> p </span><span style="color: #569CD6">IS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">THEN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">RETURN</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;-&#39;</span><span style="color: #D4D4D4">; </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">IF</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">    l_day  := EXTRACT(</span><span style="color: #569CD6">DAY</span><span style="color: #D4D4D4">    </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> p);</span></span>
<span class="line"><span style="color: #D4D4D4">    l_hour := EXTRACT(</span><span style="color: #569CD6">HOUR</span><span style="color: #D4D4D4">   </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> p);</span></span>
<span class="line"><span style="color: #D4D4D4">    l_min  := EXTRACT(</span><span style="color: #569CD6">MINUTE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> p);</span></span>
<span class="line"><span style="color: #D4D4D4">    l_sec  := TRUNC(EXTRACT(</span><span style="color: #569CD6">SECOND</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> p));</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">RETURN</span><span style="color: #D4D4D4"> LPAD(l_day,</span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">,</span><span style="color: #CE9178">&#39;0&#39;</span><span style="color: #D4D4D4">)||</span><span style="color: #CE9178">&#39; &#39;</span><span style="color: #D4D4D4">||LPAD(l_hour,</span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">,</span><span style="color: #CE9178">&#39;0&#39;</span><span style="color: #D4D4D4">)||</span><span style="color: #CE9178">&#39;:&#39;</span><span style="color: #D4D4D4">||LPAD(l_min,</span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">,</span><span style="color: #CE9178">&#39;0&#39;</span><span style="color: #D4D4D4">)||</span><span style="color: #CE9178">&#39;:&#39;</span><span style="color: #D4D4D4">||LPAD(l_sec,</span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">,</span><span style="color: #CE9178">&#39;0&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> fmt_ds;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- ---------------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- Função auxiliar: TO_CHAR seguro para datas que podem ser NULL (retorna &#39;-&#39; no NULL)</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- ---------------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">FUNCTION</span><span style="color: #D4D4D4"> to_char_nvl(p_date </span><span style="color: #569CD6">DATE</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">RETURN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">IS</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">RETURN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">CASE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">WHEN</span><span style="color: #D4D4D4"> p_date </span><span style="color: #569CD6">IS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">THEN</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;-&#39;</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">ELSE</span><span style="color: #D4D4D4"> TO_CHAR(p_date,</span><span style="color: #CE9178">&#39;YYYY-MM-DD HH24:MI:SS&#39;</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- ---------------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- Monta o nome totalmente qualificado do job de SCHEDULER</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- ---------------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">FUNCTION</span><span style="color: #D4D4D4"> sched_job_fqname(p_owner </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">, p_job_name </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">RETURN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">IS</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">RETURN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">CASE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">WHEN</span><span style="color: #D4D4D4"> p_owner </span><span style="color: #569CD6">IS NOT NULL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">THEN</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(p_owner)||</span><span style="color: #CE9178">&#39;.&#39;</span><span style="color: #D4D4D4">||</span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(p_job_name) </span><span style="color: #569CD6">ELSE</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(p_job_name) </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- ---------------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- Solicita parada de job SCHEDULER, se estiver em execução (silencioso em falhas)</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- ---------------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">PROCEDURE</span><span style="color: #D4D4D4"> stop_scheduler_if_running(p_owner </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">, p_job_name </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">IS</span></span>
<span class="line"><span style="color: #D4D4D4">    l_fq </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">261</span><span style="color: #D4D4D4">) := sched_job_fqname(p_owner, p_job_name);</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">    DBMS_SCHEDULER.STOP_JOB(job_name =&gt; l_fq, </span><span style="color: #569CD6">force</span><span style="color: #D4D4D4"> =&gt; TRUE);</span></span>
<span class="line"><span style="color: #D4D4D4">  EXCEPTION</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">WHEN</span><span style="color: #D4D4D4"> OTHERS </span><span style="color: #569CD6">THEN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- ---------------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- Encerra sessão de DBMS_JOB, se houver (suporte RAC com @inst_id)</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- ---------------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">PROCEDURE</span><span style="color: #D4D4D4"> kill_dbms_job_session(p_job_id </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NUMBER</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">IS</span></span>
<span class="line"><span style="color: #D4D4D4">    l_sid     </span><span style="color: #569CD6">NUMBER</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">    l_serial  </span><span style="color: #569CD6">NUMBER</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">    l_inst    </span><span style="color: #569CD6">NUMBER</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">    l_stmt    </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">200</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> s.sid, s.serial#, s.inst_id</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">INTO</span><span style="color: #D4D4D4"> l_sid, l_serial, l_inst</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> dba_jobs_running r</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">JOIN</span><span style="color: #D4D4D4"> gv$</span><span style="color: #569CD6">session</span><span style="color: #D4D4D4"> s </span><span style="color: #569CD6">ON</span><span style="color: #D4D4D4"> s.sid = r.sid</span></span>
<span class="line"><span style="color: #D4D4D4">     </span><span style="color: #569CD6">WHERE</span><span style="color: #D4D4D4"> r.job = p_job_id</span></span>
<span class="line"><span style="color: #D4D4D4">       </span><span style="color: #569CD6">AND</span><span style="color: #D4D4D4"> ROWNUM = </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    l_stmt := </span><span style="color: #CE9178">&#39;ALTER SYSTEM KILL SESSION &#39;&#39;&#39;</span><span style="color: #D4D4D4">||l_sid||</span><span style="color: #CE9178">&#39;,&#39;</span><span style="color: #D4D4D4">||l_serial||</span></span>
<span class="line"><span style="color: #D4D4D4">              </span><span style="color: #569CD6">CASE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">WHEN</span><span style="color: #D4D4D4"> l_inst </span><span style="color: #569CD6">IS NOT NULL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">THEN</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;,@&#39;</span><span style="color: #D4D4D4">||l_inst </span><span style="color: #569CD6">ELSE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4">||</span><span style="color: #CE9178">&#39;&#39;&#39; IMMEDIATE&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">EXECUTE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">IMMEDIATE</span><span style="color: #D4D4D4"> l_stmt;</span></span>
<span class="line"><span style="color: #D4D4D4">  EXCEPTION</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">WHEN</span><span style="color: #D4D4D4"> NO_DATA_FOUND </span><span style="color: #569CD6">THEN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">WHEN</span><span style="color: #D4D4D4"> OTHERS </span><span style="color: #569CD6">THEN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- ---------------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- Resolve owner de job SCHEDULER quando usuário não informou p_owner</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- Lança erro se não encontrado ou se existir em múltiplos owners.</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- ---------------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">PROCEDURE</span><span style="color: #D4D4D4"> resolve_scheduler(p_owner </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">, p_job_name </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">                              o_owner </span><span style="color: #569CD6">OUT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">, o_job_name </span><span style="color: #569CD6">OUT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">IS</span></span>
<span class="line"><span style="color: #D4D4D4">    l_cnt </span><span style="color: #569CD6">INTEGER</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">    o_job_name := </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(p_job_name);</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">IF</span><span style="color: #D4D4D4"> p_owner </span><span style="color: #569CD6">IS NOT NULL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">THEN</span><span style="color: #D4D4D4"> o_owner := </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(p_owner); </span><span style="color: #569CD6">RETURN</span><span style="color: #D4D4D4">; </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">IF</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">COUNT</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">DISTINCT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">INTO</span><span style="color: #D4D4D4"> l_cnt</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> dba_scheduler_jobs</span></span>
<span class="line"><span style="color: #D4D4D4">     </span><span style="color: #569CD6">WHERE</span><span style="color: #D4D4D4"> job_name = o_job_name;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">IF</span><span style="color: #D4D4D4"> l_cnt = </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">THEN</span></span>
<span class="line"><span style="color: #D4D4D4">      RAISE NO_DATA_FOUND;</span></span>
<span class="line"><span style="color: #D4D4D4">    ELSIF l_cnt &gt; </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">THEN</span></span>
<span class="line"><span style="color: #D4D4D4">      RAISE_APPLICATION_ERROR(-</span><span style="color: #B5CEA8">20002</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #CE9178">&#39;JOB_NAME existe em múltiplos owners. Informe p_owner. JOB_NAME=&#39;</span><span style="color: #D4D4D4">||o_job_name);</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">ELSE</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">INTO</span><span style="color: #D4D4D4"> o_owner</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> dba_scheduler_jobs</span></span>
<span class="line"><span style="color: #D4D4D4">       </span><span style="color: #569CD6">WHERE</span><span style="color: #D4D4D4"> job_name = o_job_name</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #569CD6">AND</span><span style="color: #D4D4D4"> ROWNUM = </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">IF</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> resolve_scheduler;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- ---------------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- Listagem: inventário unificado</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- ---------------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">PROCEDURE</span><span style="color: #D4D4D4"> list_jobs(p_owner </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4">, p_like </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">IS</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">    DBMS_OUTPUT.PUT_LINE(</span><span style="color: #CE9178">&#39;=== JOBS (SCHEDULER) ===&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">FOR</span><span style="color: #D4D4D4"> r </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4">, job_name, </span><span style="color: #569CD6">enabled</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">state</span><span style="color: #D4D4D4">, next_run_date, job_action</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> dba_scheduler_jobs</span></span>
<span class="line"><span style="color: #D4D4D4">       </span><span style="color: #569CD6">WHERE</span><span style="color: #D4D4D4"> (p_owner </span><span style="color: #569CD6">IS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">OR</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4"> = </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(p_owner))</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #569CD6">AND</span><span style="color: #D4D4D4"> (p_like  </span><span style="color: #569CD6">IS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">OR</span><span style="color: #D4D4D4"> job_name </span><span style="color: #569CD6">LIKE</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(p_like))</span></span>
<span class="line"><span style="color: #D4D4D4">       </span><span style="color: #569CD6">ORDER BY</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4">, job_name</span></span>
<span class="line"><span style="color: #D4D4D4">    ) </span><span style="color: #569CD6">LOOP</span></span>
<span class="line"><span style="color: #D4D4D4">      DBMS_OUTPUT.PUT_LINE(r.owner||</span><span style="color: #CE9178">&#39;.&#39;</span><span style="color: #D4D4D4">||r.job_name||</span></span>
<span class="line"><span style="color: #D4D4D4">                           </span><span style="color: #CE9178">&#39; | enabled=&#39;</span><span style="color: #D4D4D4">||r.enabled||</span></span>
<span class="line"><span style="color: #D4D4D4">                           </span><span style="color: #CE9178">&#39; | state=&#39;</span><span style="color: #D4D4D4">||NVL(r.state,</span><span style="color: #CE9178">&#39;-&#39;</span><span style="color: #D4D4D4">)||</span></span>
<span class="line"><span style="color: #D4D4D4">                           </span><span style="color: #CE9178">&#39; | next=&#39;</span><span style="color: #D4D4D4">||to_char_nvl(</span><span style="color: #DCDCAA">CAST</span><span style="color: #D4D4D4">(r.next_run_date </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">DATE</span><span style="color: #D4D4D4">))||</span></span>
<span class="line"><span style="color: #D4D4D4">                           </span><span style="color: #CE9178">&#39; | action=&#39;</span><span style="color: #D4D4D4">||SUBSTR(r.job_action,</span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">,</span><span style="color: #B5CEA8">60</span><span style="color: #D4D4D4">));</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">LOOP</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    DBMS_OUTPUT.PUT_LINE(CHR(</span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">)||</span><span style="color: #CE9178">&#39;=== JOBS (DBMS_JOB) ===&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">FOR</span><span style="color: #D4D4D4"> r </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> schema_user </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4">, job </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> job_id, DECODE(broken,</span><span style="color: #CE9178">&#39;Y&#39;</span><span style="color: #D4D4D4">,</span><span style="color: #CE9178">&#39;FALSE&#39;</span><span style="color: #D4D4D4">,</span><span style="color: #CE9178">&#39;TRUE&#39;</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">enabled</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">             next_date, what</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> dba_jobs</span></span>
<span class="line"><span style="color: #D4D4D4">       </span><span style="color: #569CD6">WHERE</span><span style="color: #D4D4D4"> (p_owner </span><span style="color: #569CD6">IS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">OR</span><span style="color: #D4D4D4"> schema_user = </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(p_owner))</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #569CD6">AND</span><span style="color: #D4D4D4"> (p_like  </span><span style="color: #569CD6">IS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">OR</span><span style="color: #D4D4D4"> TO_CHAR(job) </span><span style="color: #569CD6">LIKE</span><span style="color: #D4D4D4"> p_like </span><span style="color: #569CD6">OR</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(what) </span><span style="color: #569CD6">LIKE</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(p_like))</span></span>
<span class="line"><span style="color: #D4D4D4">       </span><span style="color: #569CD6">ORDER BY</span><span style="color: #D4D4D4"> schema_user, job</span></span>
<span class="line"><span style="color: #D4D4D4">    ) </span><span style="color: #569CD6">LOOP</span></span>
<span class="line"><span style="color: #D4D4D4">      DBMS_OUTPUT.PUT_LINE(r.owner||</span><span style="color: #CE9178">&#39;.&#39;</span><span style="color: #D4D4D4">||r.job_id||</span></span>
<span class="line"><span style="color: #D4D4D4">                           </span><span style="color: #CE9178">&#39; | enabled=&#39;</span><span style="color: #D4D4D4">||r.enabled||</span></span>
<span class="line"><span style="color: #D4D4D4">                           </span><span style="color: #CE9178">&#39; | next=&#39;</span><span style="color: #D4D4D4">||to_char_nvl(r.next_date)||</span></span>
<span class="line"><span style="color: #D4D4D4">                           </span><span style="color: #CE9178">&#39; | what=&#39;</span><span style="color: #D4D4D4">||SUBSTR(r.what,</span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">,</span><span style="color: #B5CEA8">60</span><span style="color: #D4D4D4">));</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">LOOP</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> list_jobs;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- ---------------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- Listagem: execução unificada</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- ---------------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">PROCEDURE</span><span style="color: #D4D4D4"> list_running_jobs(p_owner </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4">, p_like </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">IS</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">    DBMS_OUTPUT.PUT_LINE(</span><span style="color: #CE9178">&#39;=== RUNNING (SCHEDULER) ===&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">FOR</span><span style="color: #D4D4D4"> r </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4">, job_name, session_id, running_instance, elapsed_time, cpu_used</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> dba_scheduler_running_jobs</span></span>
<span class="line"><span style="color: #D4D4D4">       </span><span style="color: #569CD6">WHERE</span><span style="color: #D4D4D4"> (p_owner </span><span style="color: #569CD6">IS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">OR</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4"> = </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(p_owner))</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #569CD6">AND</span><span style="color: #D4D4D4"> (p_like  </span><span style="color: #569CD6">IS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">OR</span><span style="color: #D4D4D4"> job_name </span><span style="color: #569CD6">LIKE</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(p_like))</span></span>
<span class="line"><span style="color: #D4D4D4">       </span><span style="color: #569CD6">ORDER BY</span><span style="color: #D4D4D4"> running_instance, job_name</span></span>
<span class="line"><span style="color: #D4D4D4">    ) </span><span style="color: #569CD6">LOOP</span></span>
<span class="line"><span style="color: #D4D4D4">      DBMS_OUTPUT.PUT_LINE(r.owner||</span><span style="color: #CE9178">&#39;.&#39;</span><span style="color: #D4D4D4">||r.job_name||</span></span>
<span class="line"><span style="color: #D4D4D4">                           </span><span style="color: #CE9178">&#39; | sid=&#39;</span><span style="color: #D4D4D4">||r.session_id||</span></span>
<span class="line"><span style="color: #D4D4D4">                           </span><span style="color: #CE9178">&#39; | inst=&#39;</span><span style="color: #D4D4D4">||r.running_instance||</span></span>
<span class="line"><span style="color: #D4D4D4">                           </span><span style="color: #CE9178">&#39; | elapsed=&#39;</span><span style="color: #D4D4D4">||fmt_ds(r.elapsed_time)||</span></span>
<span class="line"><span style="color: #D4D4D4">                           </span><span style="color: #CE9178">&#39; | cpu=&#39;</span><span style="color: #D4D4D4">||fmt_ds(r.cpu_used));</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">LOOP</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    DBMS_OUTPUT.PUT_LINE(CHR(</span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">)||</span><span style="color: #CE9178">&#39;=== RUNNING (DBMS_JOB) ===&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">FOR</span><span style="color: #D4D4D4"> r </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> j.schema_user </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4">, r.job </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> job_id, s.sid, s.serial#,</span></span>
<span class="line"><span style="color: #D4D4D4">             s.inst_id </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> running_instance,</span></span>
<span class="line"><span style="color: #D4D4D4">             NUMTODSINTERVAL(TRUNC((</span><span style="color: #569CD6">SYSDATE</span><span style="color: #D4D4D4"> - s.logon_time)*</span><span style="color: #B5CEA8">86400</span><span style="color: #D4D4D4">),</span><span style="color: #CE9178">&#39;SECOND&#39;</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> elapsed_time,</span></span>
<span class="line"><span style="color: #D4D4D4">             j.what</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> dba_jobs_running r</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">JOIN</span><span style="color: #D4D4D4"> gv$</span><span style="color: #569CD6">session</span><span style="color: #D4D4D4"> s </span><span style="color: #569CD6">ON</span><span style="color: #D4D4D4"> s.sid = r.sid</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">JOIN</span><span style="color: #D4D4D4"> dba_jobs j   </span><span style="color: #569CD6">ON</span><span style="color: #D4D4D4"> j.job = r.job</span></span>
<span class="line"><span style="color: #D4D4D4">       </span><span style="color: #569CD6">WHERE</span><span style="color: #D4D4D4"> (p_owner </span><span style="color: #569CD6">IS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">OR</span><span style="color: #D4D4D4"> j.schema_user = </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(p_owner))</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #569CD6">AND</span><span style="color: #D4D4D4"> (p_like  </span><span style="color: #569CD6">IS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">OR</span><span style="color: #D4D4D4"> TO_CHAR(r.job) </span><span style="color: #569CD6">LIKE</span><span style="color: #D4D4D4"> p_like </span><span style="color: #569CD6">OR</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(j.what) </span><span style="color: #569CD6">LIKE</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(p_like))</span></span>
<span class="line"><span style="color: #D4D4D4">       </span><span style="color: #569CD6">ORDER BY</span><span style="color: #D4D4D4"> running_instance, job_id</span></span>
<span class="line"><span style="color: #D4D4D4">    ) </span><span style="color: #569CD6">LOOP</span></span>
<span class="line"><span style="color: #D4D4D4">      DBMS_OUTPUT.PUT_LINE(r.owner||</span><span style="color: #CE9178">&#39;.&#39;</span><span style="color: #D4D4D4">||r.job_id||</span></span>
<span class="line"><span style="color: #D4D4D4">                           </span><span style="color: #CE9178">&#39; | sid=&#39;</span><span style="color: #D4D4D4">||r.sid||</span><span style="color: #CE9178">&#39;,&#39;</span><span style="color: #D4D4D4">||r.serial#||</span></span>
<span class="line"><span style="color: #D4D4D4">                           </span><span style="color: #CE9178">&#39; | inst=&#39;</span><span style="color: #D4D4D4">||r.running_instance||</span></span>
<span class="line"><span style="color: #D4D4D4">                           </span><span style="color: #CE9178">&#39; | elapsed=&#39;</span><span style="color: #D4D4D4">||fmt_ds(r.elapsed_time));</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">LOOP</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> list_running_jobs;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- ---------------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- Núcleo: habilita/desabilita por identificador (nome SCHEDULER ou número DBMS_JOB)</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- ---------------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">PROCEDURE</span><span style="color: #D4D4D4"> set_job_enabled(</span></span>
<span class="line"><span style="color: #D4D4D4">    p_job_identifier </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">    p_enable         </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">BOOLEAN</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">    p_owner          </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">    p_stop_running   </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">BOOLEAN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> FALSE</span></span>
<span class="line"><span style="color: #D4D4D4">  ) </span><span style="color: #569CD6">IS</span></span>
<span class="line"><span style="color: #D4D4D4">    l_owner    </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">128</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">    l_job_name </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">128</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">    l_job_id   </span><span style="color: #569CD6">NUMBER</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955">-- 1) Tentar SCHEDULER (nome)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">IF</span><span style="color: #D4D4D4"> REGEXP_LIKE(p_job_identifier,</span><span style="color: #CE9178">&#39;^\d+$&#39;</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">THEN</span><span style="color: #D4D4D4"> RAISE NO_DATA_FOUND; </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">IF</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">IF</span><span style="color: #D4D4D4"> INSTR(p_job_identifier,</span><span style="color: #CE9178">&#39;.&#39;</span><span style="color: #D4D4D4">) &gt; </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">THEN</span></span>
<span class="line"><span style="color: #D4D4D4">        l_owner    := </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(REGEXP_SUBSTR(p_job_identifier,</span><span style="color: #CE9178">&#39;^([^\.]+)&#39;</span><span style="color: #D4D4D4">));</span></span>
<span class="line"><span style="color: #D4D4D4">        l_job_name := </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(REGEXP_SUBSTR(p_job_identifier,</span><span style="color: #CE9178">&#39;\.([^\.]+)$&#39;</span><span style="color: #D4D4D4">,</span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">,</span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">,</span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4">,</span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">));</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">ELSE</span></span>
<span class="line"><span style="color: #D4D4D4">        l_job_name := </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(p_job_identifier);</span></span>
<span class="line"><span style="color: #D4D4D4">        resolve_scheduler(p_owner, l_job_name, l_owner, l_job_name);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">IF</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #6A9955">-- valida existência</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">DECLARE</span><span style="color: #D4D4D4"> l_dummy PLS_INTEGER;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">INTO</span><span style="color: #D4D4D4"> l_dummy</span></span>
<span class="line"><span style="color: #D4D4D4">          </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> dba_scheduler_jobs</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #569CD6">WHERE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4"> = l_owner </span><span style="color: #569CD6">AND</span><span style="color: #D4D4D4"> job_name = l_job_name </span><span style="color: #569CD6">AND</span><span style="color: #D4D4D4"> ROWNUM = </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">IF</span><span style="color: #D4D4D4"> p_stop_running </span><span style="color: #569CD6">THEN</span></span>
<span class="line"><span style="color: #D4D4D4">        stop_scheduler_if_running(l_owner, l_job_name);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">IF</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">IF</span><span style="color: #D4D4D4"> p_enable </span><span style="color: #569CD6">THEN</span></span>
<span class="line"><span style="color: #D4D4D4">        DBMS_SCHEDULER.ENABLE( sched_job_fqname(l_owner, l_job_name) );</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">ELSE</span></span>
<span class="line"><span style="color: #D4D4D4">        DBMS_SCHEDULER.DISABLE( sched_job_fqname(l_owner, l_job_name) );</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">IF</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">      DBMS_OUTPUT.PUT_LINE(</span><span style="color: #CE9178">&#39;OK (SCHEDULER) &#39;</span><span style="color: #D4D4D4">||</span></span>
<span class="line"><span style="color: #D4D4D4">        sched_job_fqname(l_owner,l_job_name)||</span><span style="color: #CE9178">&#39; =&gt; &#39;</span><span style="color: #D4D4D4">||</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">CASE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">WHEN</span><span style="color: #D4D4D4"> p_enable </span><span style="color: #569CD6">THEN</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;ENABLED&#39;</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">ELSE</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;DISABLED&#39;</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">RETURN</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">    EXCEPTION</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">WHEN</span><span style="color: #D4D4D4"> NO_DATA_FOUND </span><span style="color: #569CD6">THEN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4">; </span><span style="color: #6A9955">-- não era scheduler; tentar DBMS_JOB</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955">-- 2) Tentar DBMS_JOB (número)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">      l_job_id := TO_NUMBER(</span><span style="color: #DCDCAA">TRIM</span><span style="color: #D4D4D4">(p_job_identifier));</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #6A9955">-- valida existência (restringe owner se informado)</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">DECLARE</span><span style="color: #D4D4D4"> l_dummy2 PLS_INTEGER;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">INTO</span><span style="color: #D4D4D4"> l_dummy2</span></span>
<span class="line"><span style="color: #D4D4D4">          </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> dba_jobs</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #569CD6">WHERE</span><span style="color: #D4D4D4"> job = l_job_id</span></span>
<span class="line"><span style="color: #D4D4D4">           </span><span style="color: #569CD6">AND</span><span style="color: #D4D4D4"> (p_owner </span><span style="color: #569CD6">IS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">OR</span><span style="color: #D4D4D4"> schema_user = </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(p_owner))</span></span>
<span class="line"><span style="color: #D4D4D4">           </span><span style="color: #569CD6">AND</span><span style="color: #D4D4D4"> ROWNUM = </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">IF</span><span style="color: #D4D4D4"> p_stop_running </span><span style="color: #569CD6">THEN</span></span>
<span class="line"><span style="color: #D4D4D4">        kill_dbms_job_session(l_job_id);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">IF</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">      DBMS_JOB.BROKEN(l_job_id, </span><span style="color: #569CD6">NOT</span><span style="color: #D4D4D4"> p_enable);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">      DBMS_OUTPUT.PUT_LINE(</span><span style="color: #CE9178">&#39;OK (DBMS_JOB) &#39;</span><span style="color: #D4D4D4">||l_job_id||</span><span style="color: #CE9178">&#39; =&gt; &#39;</span><span style="color: #D4D4D4">||</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">CASE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">WHEN</span><span style="color: #D4D4D4"> p_enable </span><span style="color: #569CD6">THEN</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;ENABLED&#39;</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">ELSE</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;DISABLED&#39;</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">RETURN</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">    EXCEPTION</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">WHEN</span><span style="color: #D4D4D4"> VALUE_ERROR    </span><span style="color: #569CD6">THEN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">WHEN</span><span style="color: #D4D4D4"> INVALID_NUMBER </span><span style="color: #569CD6">THEN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">WHEN</span><span style="color: #D4D4D4"> NO_DATA_FOUND  </span><span style="color: #569CD6">THEN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955">-- 3) Não encontrado em nenhuma modalidade</span></span>
<span class="line"><span style="color: #D4D4D4">    RAISE_APPLICATION_ERROR(-</span><span style="color: #B5CEA8">20001</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #CE9178">&#39;Job não encontrado como SCHEDULER (por nome) nem DBMS_JOB (por número): &#39;</span><span style="color: #D4D4D4">||p_job_identifier);</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> set_job_enabled;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- Açúcares sintáticos</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">PROCEDURE</span><span style="color: #D4D4D4"> enable_job(</span></span>
<span class="line"><span style="color: #D4D4D4">    p_job_identifier </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">    p_owner          </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">    p_stop_running   </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">BOOLEAN</span><span style="color: #D4D4D4">  </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> FALSE</span></span>
<span class="line"><span style="color: #D4D4D4">  ) </span><span style="color: #569CD6">IS</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">    set_job_enabled(p_job_identifier =&gt; p_job_identifier,</span></span>
<span class="line"><span style="color: #D4D4D4">                    p_enable         =&gt; TRUE,</span></span>
<span class="line"><span style="color: #D4D4D4">                    p_owner          =&gt; p_owner,</span></span>
<span class="line"><span style="color: #D4D4D4">                    p_stop_running   =&gt; p_stop_running);</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">PROCEDURE</span><span style="color: #D4D4D4"> disable_job(</span></span>
<span class="line"><span style="color: #D4D4D4">    p_job_identifier </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">    p_owner          </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">    p_stop_running   </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">BOOLEAN</span><span style="color: #D4D4D4">  </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> TRUE</span></span>
<span class="line"><span style="color: #D4D4D4">  ) </span><span style="color: #569CD6">IS</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">    set_job_enabled(p_job_identifier =&gt; p_job_identifier,</span></span>
<span class="line"><span style="color: #D4D4D4">                    p_enable         =&gt; FALSE,</span></span>
<span class="line"><span style="color: #D4D4D4">                    p_owner          =&gt; p_owner,</span></span>
<span class="line"><span style="color: #D4D4D4">                    p_stop_running   =&gt; p_stop_running);</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- ---------------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- Habilita/Desabilita em lote por padrão (LIKE) e, opcionalmente, por tipo</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">-- ---------------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">PROCEDURE</span><span style="color: #D4D4D4"> set_jobs_by_pattern(</span></span>
<span class="line"><span style="color: #D4D4D4">    p_name_like     </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">    p_enable        </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">BOOLEAN</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">    p_owner         </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">    p_type          </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> c_type_any,</span></span>
<span class="line"><span style="color: #D4D4D4">    p_stop_running  </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">BOOLEAN</span><span style="color: #D4D4D4">  </span><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> FALSE</span></span>
<span class="line"><span style="color: #D4D4D4">  ) </span><span style="color: #569CD6">IS</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955">-- SCHEDULER</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">IF</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(p_type) </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> (c_type_any, c_type_scheduler) </span><span style="color: #569CD6">THEN</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">FOR</span><span style="color: #D4D4D4"> r </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4">, job_name</span></span>
<span class="line"><span style="color: #D4D4D4">          </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> dba_scheduler_jobs</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #569CD6">WHERE</span><span style="color: #D4D4D4"> (p_owner </span><span style="color: #569CD6">IS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">OR</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4"> = </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(p_owner))</span></span>
<span class="line"><span style="color: #D4D4D4">           </span><span style="color: #569CD6">AND</span><span style="color: #D4D4D4"> job_name </span><span style="color: #569CD6">LIKE</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(p_name_like)</span></span>
<span class="line"><span style="color: #D4D4D4">      ) </span><span style="color: #569CD6">LOOP</span></span>
<span class="line"><span style="color: #D4D4D4">        set_job_enabled(r.owner||</span><span style="color: #CE9178">&#39;.&#39;</span><span style="color: #D4D4D4">||r.job_name, p_enable, </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4">, p_stop_running);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">LOOP</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">IF</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955">-- DBMS_JOB</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">IF</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(p_type) </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> (c_type_any, c_type_dbms_job) </span><span style="color: #569CD6">THEN</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">FOR</span><span style="color: #D4D4D4"> r </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> schema_user </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">owner</span><span style="color: #D4D4D4">, job</span></span>
<span class="line"><span style="color: #D4D4D4">          </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> dba_jobs</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #569CD6">WHERE</span><span style="color: #D4D4D4"> (p_owner </span><span style="color: #569CD6">IS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">NULL</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">OR</span><span style="color: #D4D4D4"> schema_user = </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(p_owner))</span></span>
<span class="line"><span style="color: #D4D4D4">           </span><span style="color: #569CD6">AND</span><span style="color: #D4D4D4"> (TO_CHAR(job) </span><span style="color: #569CD6">LIKE</span><span style="color: #D4D4D4"> p_name_like </span><span style="color: #569CD6">OR</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(what) </span><span style="color: #569CD6">LIKE</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">UPPER</span><span style="color: #D4D4D4">(p_name_like))</span></span>
<span class="line"><span style="color: #D4D4D4">      ) </span><span style="color: #569CD6">LOOP</span></span>
<span class="line"><span style="color: #D4D4D4">        set_job_enabled(TO_CHAR(r.job), p_enable, r.owner, p_stop_running);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">LOOP</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">IF</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> set_jobs_by_pattern;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> pkg_job_admin;</span></span>
<span class="line"><span style="color: #D4D4D4">/</span></span>
<span class="line"><span style="color: #D4D4D4">SHOW ERRORS</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">PROMPT ✓ Pacote criado/atualizado com sucesso.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">PROMPT</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT ── </span><span style="color: #B5CEA8">4</span><span style="color: #D4D4D4">) Segurança: </span><span style="color: #569CD6">ROLE</span><span style="color: #D4D4D4">, Grants e Sinônimos Públicos …</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">-- =================================================================================================</span></span>
<span class="line"><span style="color: #6A9955">-- 4.1) ROLE — criada apenas se não existir</span></span>
<span class="line"><span style="color: #6A9955">-- =================================================================================================</span></span>
<span class="line"><span style="color: #569CD6">DECLARE</span></span>
<span class="line"><span style="color: #D4D4D4">  l_cnt </span><span style="color: #569CD6">INTEGER</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">COUNT</span><span style="color: #D4D4D4">(*) </span><span style="color: #569CD6">INTO</span><span style="color: #D4D4D4"> l_cnt </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> dba_roles </span><span style="color: #569CD6">WHERE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">role</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&#39;JOBDBMSSCHEDULERALL&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">IF</span><span style="color: #D4D4D4"> l_cnt = </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">THEN</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">EXECUTE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">IMMEDIATE</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;CREATE ROLE JOBDBMSSCHEDULERALL&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">    DBMS_OUTPUT.PUT_LINE(</span><span style="color: #CE9178">&#39;Role JOBDBMSSCHEDULERALL criada.&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">ELSE</span></span>
<span class="line"><span style="color: #D4D4D4">    DBMS_OUTPUT.PUT_LINE(</span><span style="color: #CE9178">&#39;Role JOBDBMSSCHEDULERALL já existente.&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">IF</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">/</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">-- =================================================================================================</span></span>
<span class="line"><span style="color: #6A9955">-- 4.2) GRANTS — executar o pacote e consultar as views por meio da ROLE</span></span>
<span class="line"><span style="color: #6A9955">-- =================================================================================================</span></span>
<span class="line"><span style="color: #569CD6">GRANT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">EXECUTE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">ON</span><span style="color: #D4D4D4"> pkg_job_admin        </span><span style="color: #569CD6">TO</span><span style="color: #D4D4D4"> JOBDBMSSCHEDULERALL;</span></span>
<span class="line"><span style="color: #569CD6">GRANT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4">  </span><span style="color: #569CD6">ON</span><span style="color: #D4D4D4"> job_admin_all_jobs   </span><span style="color: #569CD6">TO</span><span style="color: #D4D4D4"> JOBDBMSSCHEDULERALL;</span></span>
<span class="line"><span style="color: #569CD6">GRANT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4">  </span><span style="color: #569CD6">ON</span><span style="color: #D4D4D4"> job_admin_running    </span><span style="color: #569CD6">TO</span><span style="color: #D4D4D4"> JOBDBMSSCHEDULERALL;</span></span>
<span class="line"><span style="color: #569CD6">GRANT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4">  </span><span style="color: #569CD6">ON</span><span style="color: #D4D4D4"> job_admin_all_jobs_v </span><span style="color: #569CD6">TO</span><span style="color: #D4D4D4"> JOBDBMSSCHEDULERALL;</span></span>
<span class="line"><span style="color: #569CD6">GRANT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4">  </span><span style="color: #569CD6">ON</span><span style="color: #D4D4D4"> job_admin_running_v  </span><span style="color: #569CD6">TO</span><span style="color: #D4D4D4"> JOBDBMSSCHEDULERALL;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">-- =================================================================================================</span></span>
<span class="line"><span style="color: #6A9955">-- 4.3) SINÔNIMOS PÚBLICOS — apontam para os objetos do OWNER atual</span></span>
<span class="line"><span style="color: #6A9955">--     Observação: garantem uso uniforme via “public synonyms” para quem tiver a ROLE.</span></span>
<span class="line"><span style="color: #6A9955">-- =================================================================================================</span></span>
<span class="line"><span style="color: #569CD6">DECLARE</span></span>
<span class="line"><span style="color: #D4D4D4">  l_owner </span><span style="color: #569CD6">VARCHAR2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">128</span><span style="color: #D4D4D4">) := USER;</span></span>
<span class="line"><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">EXECUTE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">IMMEDIATE</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;CREATE OR REPLACE PUBLIC SYNONYM job_admin_all_jobs   FOR &#39;</span><span style="color: #D4D4D4">||l_owner||</span><span style="color: #CE9178">&#39;.job_admin_all_jobs&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">EXECUTE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">IMMEDIATE</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;CREATE OR REPLACE PUBLIC SYNONYM job_admin_running    FOR &#39;</span><span style="color: #D4D4D4">||l_owner||</span><span style="color: #CE9178">&#39;.job_admin_running&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">EXECUTE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">IMMEDIATE</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;CREATE OR REPLACE PUBLIC SYNONYM job_admin_all_jobs_v FOR &#39;</span><span style="color: #D4D4D4">||l_owner||</span><span style="color: #CE9178">&#39;.job_admin_all_jobs_v&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">EXECUTE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">IMMEDIATE</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;CREATE OR REPLACE PUBLIC SYNONYM job_admin_running_v  FOR &#39;</span><span style="color: #D4D4D4">||l_owner||</span><span style="color: #CE9178">&#39;.job_admin_running_v&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">EXECUTE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">IMMEDIATE</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;CREATE OR REPLACE PUBLIC SYNONYM pkg_job_admin        FOR &#39;</span><span style="color: #D4D4D4">||l_owner||</span><span style="color: #CE9178">&#39;.pkg_job_admin&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  DBMS_OUTPUT.PUT_LINE(</span><span style="color: #CE9178">&#39;Sinônimos públicos criados/atualizados.&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">/</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">PROMPT ✓ Segurança configurada (</span><span style="color: #569CD6">ROLE</span><span style="color: #D4D4D4"> + grants + sinônimos públicos).</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">PROMPT</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT ── </span><span style="color: #B5CEA8">5</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">Auto</span><span style="color: #D4D4D4">-Validação (não intrusiva) …</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">-- =================================================================================================</span></span>
<span class="line"><span style="color: #6A9955">-- 5.1) Verifica erros de compilação do pacote</span></span>
<span class="line"><span style="color: #6A9955">-- =================================================================================================</span></span>
<span class="line"><span style="color: #569CD6">DECLARE</span></span>
<span class="line"><span style="color: #D4D4D4">  l_errs </span><span style="color: #569CD6">INTEGER</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">COUNT</span><span style="color: #D4D4D4">(*) </span><span style="color: #569CD6">INTO</span><span style="color: #D4D4D4"> l_errs</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> user_errors</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">WHERE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">name</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&#39;PKG_JOB_ADMIN&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">IF</span><span style="color: #D4D4D4"> l_errs = </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">THEN</span></span>
<span class="line"><span style="color: #D4D4D4">    DBMS_OUTPUT.PUT_LINE(</span><span style="color: #CE9178">&#39;Pacote PKG_JOB_ADMIN sem erros de compilação.&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">ELSE</span></span>
<span class="line"><span style="color: #D4D4D4">    DBMS_OUTPUT.PUT_LINE(</span><span style="color: #CE9178">&#39;ATENÇÃO: Encontrado(s) &#39;</span><span style="color: #D4D4D4">||l_errs||</span><span style="color: #CE9178">&#39; erro(s) em PKG_JOB_ADMIN:&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">FOR</span><span style="color: #D4D4D4"> r </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">type</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">name</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">line</span><span style="color: #D4D4D4">, position, SUBSTR(</span><span style="color: #569CD6">text</span><span style="color: #D4D4D4">,</span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">,</span><span style="color: #B5CEA8">200</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">text</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> user_errors</span></span>
<span class="line"><span style="color: #D4D4D4">       </span><span style="color: #569CD6">WHERE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">name</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&#39;PKG_JOB_ADMIN&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">       </span><span style="color: #569CD6">ORDER BY</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">sequence</span></span>
<span class="line"><span style="color: #D4D4D4">    ) </span><span style="color: #569CD6">LOOP</span></span>
<span class="line"><span style="color: #D4D4D4">      DBMS_OUTPUT.PUT_LINE(r.type||</span><span style="color: #CE9178">&#39; &#39;</span><span style="color: #D4D4D4">||r.name||</span><span style="color: #CE9178">&#39; @&#39;</span><span style="color: #D4D4D4">||r.line||</span><span style="color: #CE9178">&#39;:&#39;</span><span style="color: #D4D4D4">||r.position||</span><span style="color: #CE9178">&#39; - &#39;</span><span style="color: #D4D4D4">||r.text);</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">LOOP</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">IF</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">/</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">-- =================================================================================================</span></span>
<span class="line"><span style="color: #6A9955">-- 5.2) Validação simples de acesso às views (sanidade)</span></span>
<span class="line"><span style="color: #6A9955">-- =================================================================================================</span></span>
<span class="line"><span style="color: #569CD6">DECLARE</span></span>
<span class="line"><span style="color: #D4D4D4">  l_all </span><span style="color: #569CD6">NUMBER</span><span style="color: #D4D4D4">; l_run </span><span style="color: #569CD6">NUMBER</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">COUNT</span><span style="color: #D4D4D4">(*) </span><span style="color: #569CD6">INTO</span><span style="color: #D4D4D4"> l_all </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> job_admin_all_jobs </span><span style="color: #569CD6">WHERE</span><span style="color: #D4D4D4"> ROWNUM &lt;= </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">COUNT</span><span style="color: #D4D4D4">(*) </span><span style="color: #569CD6">INTO</span><span style="color: #D4D4D4"> l_run </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> job_admin_running  </span><span style="color: #569CD6">WHERE</span><span style="color: #D4D4D4"> ROWNUM &lt;= </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  DBMS_OUTPUT.PUT_LINE(</span><span style="color: #CE9178">&#39;Views acessíveis: JOB_ADMIN_ALL_JOBS e JOB_ADMIN_RUNNING OK.&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">/</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">PROMPT</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT ── </span><span style="color: #B5CEA8">6</span><span style="color: #D4D4D4">) Exemplos de Uso (para referência; copiar/colar quando necessário) …</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">PROMPT</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">-- Inventário:</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT   pkg_job_admin.list_jobs;                          </span><span style="color: #6A9955">-- todos os jobs</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT   pkg_job_admin.list_jobs(</span><span style="color: #CE9178">&#39;DEMOAPP&#39;</span><span style="color: #D4D4D4">);               </span><span style="color: #6A9955">-- por owner</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT   pkg_job_admin.list_jobs(p_like =&gt; </span><span style="color: #CE9178">&#39;JOB_%&#39;</span><span style="color: #D4D4D4">);       </span><span style="color: #6A9955">-- por padrão (LIKE)</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT /</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">-- Em execução agora:</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT   pkg_job_admin.list_running_jobs;                       </span><span style="color: #6A9955">-- tudo</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT   pkg_job_admin.list_running_jobs(</span><span style="color: #CE9178">&#39;DEMOAPP&#39;</span><span style="color: #D4D4D4">);            </span><span style="color: #6A9955">-- por owner</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT   pkg_job_admin.list_running_jobs(p_like =&gt; </span><span style="color: #CE9178">&#39;SYNC_%&#39;</span><span style="color: #D4D4D4">);   </span><span style="color: #6A9955">-- por padrão (LIKE)</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT /</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">-- Operações pontuais:</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">-- SCHEDULER (por nome; owner opcional se único no banco)</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">-- BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">--   pkg_job_admin.disable_job(&#39;DEMOAPP.JOB_ATUALIZA_INDICES&#39;, p_stop_running =&gt; TRUE);</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">--   pkg_job_admin.enable_job (&#39;DEMOAPP.JOB_ATUALIZA_INDICES&#39;);</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">-- END;</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">-- /</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">-- DBMS_JOB (por número; owner apenas para validar pertinência quando desejar)</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">-- BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">--   pkg_job_admin.disable_job(&#39;128&#39;, p_owner =&gt; &#39;SYS&#39;, p_stop_running =&gt; TRUE);</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">--   pkg_job_admin.enable_job (&#39;128&#39;, p_owner =&gt; &#39;SYS&#39;);</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">-- END;</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">-- /</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">-- Lote por padrão (por tipo):</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">-- BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">--   pkg_job_admin.set_jobs_by_pattern(</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">--     p_name_like    =&gt; &#39;JOB_SYNC_%&#39;,</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">--     p_enable       =&gt; FALSE,</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">--     p_owner        =&gt; &#39;DEMOAPP&#39;,</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">--     p_type         =&gt; pkg_job_admin.c_type_scheduler, -- SCHEDULER | DBMS_JOB | ANY</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">--     p_stop_running =&gt; TRUE</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">--   );</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">-- END;</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">-- /</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">-- Visões consolidadas:</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">-- SELECT * FROM job_admin_all_jobs_v ORDER BY owner, job_type, job_name;</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT </span><span style="color: #6A9955">-- SELECT * FROM job_admin_running_v  ORDER BY running_instance, job_type, job_name;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">PROMPT</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT ═════════════════════════════════════════════════════════════════════════════════════════════</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT   Conclusão: job_admin_setup_completo.sql executado.</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT   Para conceder a </span><span style="color: #569CD6">ROLE</span><span style="color: #D4D4D4"> a um usuário final, utilize:</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT     </span><span style="color: #569CD6">GRANT</span><span style="color: #D4D4D4"> JOBDBMSSCHEDULERALL </span><span style="color: #569CD6">TO</span><span style="color: #D4D4D4"> nome_do_usuario;</span></span>
<span class="line"><span style="color: #D4D4D4">PROMPT ═════════════════════════════════════════════════════════════════════════════════════════════</span></span>
<span class="line"></span></code></pre></div>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Estruturas de Armazenamento do Oracle</title>
		<link>https://furushima.com.br/blog/estruturas-de-armazenamento-do-oracle/</link>
		
		<dc:creator><![CDATA[Weverton Amorim]]></dc:creator>
		<pubDate>Tue, 10 Jun 2025 10:59:20 +0000</pubDate>
				<category><![CDATA[Banco De Dados]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Banco de Dados]]></category>
		<category><![CDATA[ORACLE]]></category>
		<guid isPermaLink="false">https://furushima.com.br/?p=2841</guid>

					<description><![CDATA[Como o Oracle armazena os dados? A estrutura de armazenamento do Oracle Database é projetada para ser altamente eficiente e flexível, permitindo o armazenamento e o gerenciamento de grandes volumes de dados de forma organizada e segura. Visão Geral da Estrutura de Armazenamento O Oracle organiza os dados em várias camadas hierárquicas, garantindo escalabilidade e [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h3 class="wp-block-heading">Como o Oracle armazena os dados?</h3>



<p>A estrutura de armazenamento do <strong>Oracle Database</strong> é projetada para ser altamente eficiente e flexível, permitindo o armazenamento e o gerenciamento de grandes volumes de dados de forma organizada e segura. </p>



<h3 class="wp-block-heading">Visão Geral da Estrutura de Armazenamento</h3>



<p>O Oracle organiza os dados em várias camadas hierárquicas, garantindo escalabilidade e otimização. As principais estruturas de armazenamento do Oracle são:</p>



<ul class="wp-block-list">
<li><strong>Database</strong> (Banco de dados)</li>



<li><strong>Tablespace</strong></li>



<li><strong>Segment</strong></li>



<li><strong>Extent</strong></li>



<li><strong>Oracle Data Block</strong></li>
</ul>



<p>Cada um desses níveis desempenha um papel importante na organização e armazenamento dos dados.</p>



<h3 class="wp-block-heading">Database</h3>



<p>No nível mais alto da hierarquia, temos o <strong>Database</strong>. O banco de dados Oracle é composto por vários arquivos de dados que armazenam as informações do usuário e os metadados necessários para o funcionamento do sistema. Ele é o contêiner principal que engloba todos os outros componentes de armazenamento.</p>



<p>O Oracle Database é composto por três tipos principais de arquivos:</p>



<ul class="wp-block-list">
<li><strong>Datafiles</strong>: Armazenam os dados reais.</li>



<li><strong>Redo Log Files</strong>: Guardam um histórico das alterações no banco, usados para recuperação em caso de falhas.</li>



<li><strong>Control Files</strong>: Contêm informações estruturais sobre o banco, como a localização dos datafiles e redo logs.</li>
</ul>



<figure class="wp-block-image size-full"><img alt="" fetchpriority="high" decoding="async" width="823" height="695" src="https://furushima.com.br/wp-content/uploads/2025/06/image.png" alt="" class="wp-image-2842" srcset="https://furushima.com.br/wp-content/uploads/2025/06/image.png 823w, https://furushima.com.br/wp-content/uploads/2025/06/image-300x253.png 300w, https://furushima.com.br/wp-content/uploads/2025/06/image-768x649.png 768w" sizes="(max-width: 823px) 100vw, 823px" /></figure>



<h3 class="wp-block-heading">Tablespace</h3>



<p>O <strong>Tablespace</strong> é o próximo nível da hierarquia e age como um contêiner lógico para organizar os dados dentro do banco de dados. Ele agrupa múltiplos <strong>datafiles</strong>, que são arquivos físicos no sistema operacional onde os dados reais são armazenados. Um banco de dados pode ter vários tablespaces, sendo cada um especializado em armazenar diferentes tipos de objetos de dados.</p>



<p>Os <strong>tablespaces</strong> podem ser divididos em dois tipos principais:</p>



<ul class="wp-block-list">
<li><strong>Permanent Tablespaces</strong>: Armazenam dados persistentes, como tabelas e índices.</li>



<li><strong>Temporary Tablespaces</strong>: Usados para operações temporárias, como ordenações ou junções de dados durante consultas.</li>
</ul>



<p>Exemplos comuns de tablespaces incluem:</p>



<ul class="wp-block-list">
<li><strong>SYSTEM</strong>: Onde ficam os dicionários de dados (metadados do banco).</li>



<li><strong>SYSAUX</strong>: Um tablespace auxiliar para armazenar componentes não-críticos, como o AWR.</li>



<li><strong>USERS</strong>: Um tablespace típico onde são armazenados os dados dos usuários.</li>
</ul>



<figure class="wp-block-image size-full"><img alt="" decoding="async" width="650" height="495" src="https://furushima.com.br/wp-content/uploads/2025/06/image-1.png" alt="" class="wp-image-2843" srcset="https://furushima.com.br/wp-content/uploads/2025/06/image-1.png 650w, https://furushima.com.br/wp-content/uploads/2025/06/image-1-300x228.png 300w" sizes="(max-width: 650px) 100vw, 650px" /></figure>



<h3 class="wp-block-heading">Segment</h3>



<p>Dentro de cada <strong>tablespace</strong>, encontramos os <strong>segments</strong>. Um <strong>segmento</strong> é um espaço lógico alocado para armazenar um tipo específico de objeto de banco de dados, como uma <strong>tabela</strong>, <strong>índice</strong>, <strong>view materializada</strong>, <strong>rollback segment</strong>, etc.</p>



<p>Cada tipo de segmento desempenha um papel específico:</p>



<ul class="wp-block-list">
<li><strong>Data Segments</strong>: Armazenam os dados reais das tabelas.</li>



<li><strong>Index Segments</strong>: Contêm os índices de tabelas para melhorar a performance de busca.</li>



<li><strong>Temporary Segments</strong>: Usados para operações temporárias, como ao realizar consultas grandes.</li>



<li><strong>Undo Segments</strong>: Utilizados para manter o controle das transações para garantir a consistência dos dados e permitir rollback.</li>
</ul>



<p>Os segmentos são compostos por unidades de espaço chamadas <strong>extents</strong>.</p>



<h3 class="wp-block-heading">Extent</h3>



<p>Um <strong>extent</strong> é uma unidade contígua de espaço dentro de um segmento, onde os dados são armazenados fisicamente nos datafiles. Um segmento é composto por um ou mais extents, que são alocados conforme necessário para acomodar o crescimento do objeto de banco de dados (como uma tabela que aumenta de tamanho).</p>



<p>Quando um segmento precisa de mais espaço, o Oracle aloca um novo extent para ele. Os extents garantem que os dados sejam armazenados em blocos contínuos, o que melhora a eficiência de leitura/escrita.</p>



<figure class="wp-block-image size-full"><img alt="" decoding="async" width="607" height="406" src="https://furushima.com.br/wp-content/uploads/2025/06/image-2.png" alt="" class="wp-image-2844" srcset="https://furushima.com.br/wp-content/uploads/2025/06/image-2.png 607w, https://furushima.com.br/wp-content/uploads/2025/06/image-2-300x201.png 300w" sizes="(max-width: 607px) 100vw, 607px" /></figure>



<h3 class="wp-block-heading">Oracle Data Block</h3>



<p>O nível mais baixo da hierarquia de armazenamento é o <strong>Oracle Data Block</strong>, também chamado de <strong>database block</strong> ou <strong>data block</strong>. Os <strong>data blocks</strong> representam a menor unidade de armazenamento no Oracle Database. Cada <strong>extent</strong> é composto de múltiplos <strong>data blocks</strong>.</p>



<p>Os <strong>data blocks</strong> armazenam os dados reais, como as linhas de uma tabela. Eles são a interface entre o banco de dados e o sistema de arquivos subjacente. O tamanho dos <strong>data blocks</strong> é configurável e pode variar (tipicamente 4KB, 8KB, 16KB ou 32KB), dependendo das necessidades do ambiente.</p>



<p>Os <strong>data blocks</strong> contêm várias informações, além dos dados do usuário, como cabeçalhos que registram metadados importantes, como o endereço do bloco e informações de transações.</p>



<h3 class="wp-block-heading">Componentes de um Oracle Data Block</h3>



<p>Um <strong>data block</strong> possui várias subestruturas:</p>



<ol class="wp-block-list">
<li><strong>Cabeçalho do Bloco (Block Header)</strong>: Contém metadados sobre o bloco, como o endereço do bloco, identificadores de transações ativas e status de formatação.</li>



<li><strong>Tabela de Diretório (Table Directory)</strong>: Mantém informações sobre as tabelas cujos dados estão armazenados neste bloco (importante em caso de blocos com dados de mais de uma tabela).</li>



<li><strong>Tabela de Linhas (Row Directory)</strong>: Lista de ponteiros para as linhas reais armazenadas no bloco.</li>



<li><strong>Linhas de Dados</strong>: São os dados reais das colunas de uma tabela.</li>



<li><strong>Espaço Livre (Free Space)</strong>: Espaço não utilizado no bloco que pode ser usado para inserções futuras ou expansões de linhas.</li>



<li><strong>Gerenciamento de Espaço</strong>: O Oracle utiliza métodos sofisticados para o gerenciamento de espaço dentro dos blocos, como o <strong>PCTFREE</strong> (percentual de espaço reservado para futuras atualizações) e <strong>PCTUSED</strong> (percentual de ocupação após o qual novos dados podem ser inseridos no bloco).</li>
</ol>



<figure class="wp-block-image size-full is-resized"><img alt="" loading="lazy" decoding="async" width="737" height="781" src="https://furushima.com.br/wp-content/uploads/2025/06/image-3.png" alt="" class="wp-image-2845" style="width:741px;height:auto" srcset="https://furushima.com.br/wp-content/uploads/2025/06/image-3.png 737w, https://furushima.com.br/wp-content/uploads/2025/06/image-3-283x300.png 283w" sizes="(max-width: 737px) 100vw, 737px" /></figure>



<h3 class="wp-block-heading">Tabelas e Índices no Oracle Data Block</h3>



<p>Os <strong>data blocks</strong> podem armazenar dados de tabelas e índices. Ao trabalhar com tabelas:</p>



<ul class="wp-block-list">
<li>As <strong>linhas</strong> da tabela são armazenadas dentro dos <strong>data blocks</strong>.</li>



<li>Em caso de atualização, se a linha de dados crescer e não couber no bloco original, pode ocorrer a <strong>migração de linhas</strong> ou <strong>encadeamento de linhas</strong>, em que a linha é movida para outro bloco, o que pode afetar a performance.</li>
</ul>



<p>No caso de índices, os <strong>data blocks</strong> são usados para armazenar as estruturas de árvore B-tree que organizam e aceleram a busca de dados.</p>



<figure class="wp-block-image size-full"><img alt="" loading="lazy" decoding="async" width="770" height="673" src="https://furushima.com.br/wp-content/uploads/2025/06/image-4.png" alt="" class="wp-image-2846" srcset="https://furushima.com.br/wp-content/uploads/2025/06/image-4.png 770w, https://furushima.com.br/wp-content/uploads/2025/06/image-4-300x262.png 300w, https://furushima.com.br/wp-content/uploads/2025/06/image-4-768x671.png 768w" sizes="(max-width: 770px) 100vw, 770px" /></figure>



<figure class="wp-block-image size-full"><img alt="" loading="lazy" decoding="async" width="538" height="352" src="https://furushima.com.br/wp-content/uploads/2025/06/image-5.png" alt="" class="wp-image-2847" srcset="https://furushima.com.br/wp-content/uploads/2025/06/image-5.png 538w, https://furushima.com.br/wp-content/uploads/2025/06/image-5-300x196.png 300w" sizes="(max-width: 538px) 100vw, 538px" /></figure>



<p><br>No <strong>Oracle Database</strong>, a parametrização de armazenamento em uma tabela, definida pela cláusula <strong>STORAGE</strong>, determina como o espaço em disco será alocado e gerenciado para essa tabela. Esses parâmetros são essenciais para otimizar o uso de espaço, controlar o crescimento dos segmentos e reduzir a fragmentação. Eles influenciam aspectos como o tamanho dos extents, a reserva de espaço para atualizações futuras e a frequência de alocação de novos extents. Vamos explorar esses parâmetros com base na tabela de exemplo <strong>&#8220;empregados&#8221;</strong>:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="CREATE TABLE empregados (
    empregado_id NUMBER PRIMARY KEY,
    nome VARCHAR2(100),
    cargo VARCHAR2(50),
    salario NUMBER(10, 2),
    data_admissao DATE DEFAULT SYSDATE,
    departamento_id NUMBER,
    CONSTRAINT fk_departamento
    FOREIGN KEY (departamento_id) REFERENCES departamentos(departamento_id)
) TABLESPACE meu_tablespace
STORAGE (
    INITIAL 64K
    NEXT 128K
    PCTINCREASE 0
)
PCTFREE 10
PCTUSED 40;" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #4FC1FF">CREATE</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">TABLE</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">empregados</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">empregado_id</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">NUMBER</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">PRIMARY</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">KEY</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">nome</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">VARCHAR2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">100</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">cargo</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">VARCHAR2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">50</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">salario</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">NUMBER</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">data_admissao</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">DATE</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">DEFAULT</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">SYSDATE</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">departamento_id</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">NUMBER</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #4FC1FF">CONSTRAINT</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">fk_departamento</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #4FC1FF">FOREIGN</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">KEY</span><span style="color: #D4D4D4"> (</span><span style="color: #9CDCFE">departamento_id</span><span style="color: #D4D4D4">) </span><span style="color: #4FC1FF">REFERENCES</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">departamentos</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">departamento_id</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">) </span><span style="color: #4FC1FF">TABLESPACE</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">meu_tablespace</span></span>
<span class="line"><span style="color: #DCDCAA">STORAGE</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #4FC1FF">INITIAL</span><span style="color: #D4D4D4"> 64</span><span style="color: #4FC1FF">K</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #4FC1FF">NEXT</span><span style="color: #D4D4D4"> 128</span><span style="color: #4FC1FF">K</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #4FC1FF">PCTINCREASE</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">0</span></span>
<span class="line"><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #4FC1FF">PCTFREE</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">10</span></span>
<span class="line"><span style="color: #4FC1FF">PCTUSED</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">40</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<h3 class="wp-block-heading">Parâmetros de Armazenamento (STORAGE Clause)</h3>



<h3 class="wp-block-heading">1. INITIAL</h3>



<ul class="wp-block-list">
<li><strong>Descrição</strong>: Define o tamanho do primeiro <strong>extent</strong> alocado para o segmento da tabela. Um <strong>extent</strong> é uma unidade contígua de espaço no disco alocada para armazenar dados.</li>



<li><strong>Exemplo</strong>: <kbd>"INITIAL 64K"</kbd> significa que o primeiro extent terá 64 kilobytes. Isso determina o espaço inicial reservado para a tabela ao ser criada, influenciando a capacidade inicial de armazenamento.</li>
</ul>



<h3 class="wp-block-heading">2. NEXT</h3>



<ul class="wp-block-list">
<li><strong>Descrição</strong>: Especifica o tamanho dos <strong>extents</strong> subsequentes alocados após o primeiro. À medida que a tabela cresce e o primeiro extent é preenchido, um novo extent é alocado com o tamanho definido aqui.</li>



<li><strong>Exemplo</strong>: <kbd>"NEXT 128K"</kbd> indica que cada novo extent alocado após o primeiro terá 128 kilobytes. Esse valor ajuda a controlar o crescimento da tabela ao longo do tempo, garantindo alocações eficientes de espaço.</li>
</ul>



<h3 class="wp-block-heading">3. PCTINCREASE</h3>



<ul class="wp-block-list">
<li><strong>Descrição</strong>: Define a porcentagem de aumento de cada novo extent em relação ao anterior. Isso controla o crescimento progressivo dos extents.</li>



<li><strong>Exemplo</strong>: <kbd>"PCTINCREASE 0"</kbd> indica que todos os extents subsequentes terão o mesmo tamanho definido em <kbd>"NEXT"</kbd>, ou seja, 128K. Se fosse configurado um valor diferente de zero, cada novo extent seria maior que o anterior, aumentando pela porcentagem especificada. Por exemplo, se <kbd>"PCTINCREASE"</kbd> fosse 50, o próximo extent após 128K seria 192K (50% maior).</li>
</ul>



<h3 class="wp-block-heading">Outros Parâmetros de Tabela</h3>



<h3 class="wp-block-heading">1. PCTFREE</h3>



<ul class="wp-block-list">
<li><strong>Descrição</strong>: Determina a porcentagem de espaço em cada <strong>data block</strong> que é reservada para futuras atualizações de linhas já existentes. Isso garante que, ao alterar valores de uma linha, o bloco tenha espaço suficiente para armazenar os novos dados sem precisar movê-los para um bloco diferente.</li>



<li><strong>Exemplo</strong>: <kbd>"PCTFREE 10"</kbd> reserva 10% de cada <strong>data block</strong> para atualizações futuras. Se uma linha for atualizada e seus novos dados excederem o espaço previamente alocado para ela, os 10% reservados serão usados para evitar a migração de linhas para outros blocos, o que poderia impactar a performance.</li>
</ul>



<h3 class="wp-block-heading">2. PCTUSED</h3>



<ul class="wp-block-list">
<li><strong>Descrição</strong>: Define a porcentagem mínima de ocupação de um <strong>data block</strong> antes que ele seja reutilizado para novas inserções de dados. Após a exclusão ou movimentação de linhas, se o percentual de uso do bloco cair abaixo desse limite, o bloco será reutilizado para novas inserções.</li>



<li><strong>Exemplo</strong>: <kbd>"PCTUSED 40"</kbd> indica que, quando a ocupação do bloco cair abaixo de 40%, ele será marcado como disponível para novas inserções de dados. Esse parâmetro ajuda a evitar fragmentação e melhora a eficiência na reutilização de blocos parcialmente cheios.</li>
</ul>



<h3 class="wp-block-heading">Como Esses Parâmetros Funcionam Juntos</h3>



<ol class="wp-block-list">
<li><strong>Alocação Inicial e Crescimento de Extents</strong>:
<ul class="wp-block-list">
<li>Ao criar a tabela, o Oracle aloca um <strong>extent</strong> inicial de 64K, conforme definido em <kbd>"INITIAL"</kbd>. À medida que os dados são inseridos e o extent inicial é preenchido, o Oracle aloca novos <strong>extents</strong> de 128K, conforme especificado em <kbd>"NEXT"</kbd>. Como <kbd>"PCTINCREASE"</kbd> está definido como 0, todos os extents subsequentes terão o mesmo tamanho de 128K. Isso mantém o crescimento linear e previsível da tabela.</li>
</ul>
</li>



<li><strong>Gerenciamento de Espaço Livre em Data Blocks</strong>:
<ul class="wp-block-list">
<li>O parâmetro <kbd>"PCTFREE 10"</kbd> garante que 10% de cada <strong>data block</strong> seja reservado para atualizações de dados. Isso é importante para evitar que atualizações frequentes de linhas movam os dados para novos blocos, o que reduziria a eficiência de leitura. Esse espaço reservado permite que as linhas cresçam dentro do mesmo bloco.</li>



<li>O parâmetro <kbd>"PCTUSED 40"</kbd> garante que blocos parcialmente utilizados sejam reutilizados para novas inserções quando sua ocupação cair abaixo de 40%. Isso ajuda a evitar o desperdício de espaço em blocos que não estão completamente cheios e reduz a necessidade de alocar novos blocos, otimizando o uso do espaço.</li>
</ul>
</li>
</ol>



<h3 class="wp-block-heading">Benefícios da Configuração Correta dos Parâmetros de Armazenamento</h3>



<p>Ao configurar corretamente os parâmetros de armazenamento, é possível otimizar o uso de espaço e melhorar a performance da tabela. Esses parâmetros permitem ao DBA:</p>



<ul class="wp-block-list">
<li><strong>Controlar o crescimento do segmento</strong>: Ao especificar tamanhos adequados para os extents e definir políticas claras para a alocação subsequente, o crescimento da tabela é gerenciado de maneira eficiente, evitando fragmentação excessiva.</li>



<li><strong>Gerenciar atualizações e inserções</strong>: Parâmetros como <kbd>"PCTFREE"</kbd> e <kbd>"PCTUSED"</kbd> garantem que os blocos de dados sejam utilizados de forma inteligente, reservando espaço para atualizações e reutilizando blocos que ficaram abaixo da ocupação mínima.</li>



<li><strong>Prevenir fragmentação</strong>: O controle da alocação de extents e a reutilização de blocos parcialmente ocupados ajudam a minimizar a fragmentação, o que melhora a performance de leitura e escrita no banco de dados.</li>
</ul>



<p></p>



<p>Esses parâmetros, quando bem configurados, são ferramentas poderosas para otimizar o armazenamento e o desempenho de tabelas no Oracle Database, garantindo uma utilização eficiente dos recursos de hardware e mantendo a performance à medida que a tabela cresce e é atualizada ao longo do tempo.</p>



<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Oracle Database Fases de Startup/Shutdown</title>
		<link>https://furushima.com.br/blog/oracle-database-fases-de-startup-shutdown/</link>
		
		<dc:creator><![CDATA[Weverton Amorim]]></dc:creator>
		<pubDate>Tue, 29 Apr 2025 15:11:13 +0000</pubDate>
				<category><![CDATA[Banco De Dados]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[ORACLE]]></category>
		<guid isPermaLink="false">https://furushima.com.br/?p=2818</guid>

					<description><![CDATA[Iniciando a instância do banco de dados Oracle Antes que os usuários possam se conectar a uma instância de banco de dados, um administrador de banco de dados deve iniciar a instância do banco de dados. A instância e o banco de dados passam por estágios à medida que o banco de dados é disponibilizado [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h3 class="wp-block-heading">Iniciando a instância do banco de dados Oracle</h3>



<p><br>Antes que os usuários possam se conectar a uma instância de banco de dados, um administrador de banco de dados deve iniciar a instância do banco de dados. A instância e o banco de dados passam por estágios à medida que o banco de dados é disponibilizado para acesso pelos usuários. A instância é iniciada, o banco de dados é montado e, em seguida, o banco de dados é aberto, como mostrado no slide.</p>



<figure class="wp-block-image size-full"><img alt="" loading="lazy" decoding="async" width="1006" height="478" src="https://furushima.com.br/wp-content/uploads/2025/04/image-6.png" alt="" class="wp-image-2819" srcset="https://furushima.com.br/wp-content/uploads/2025/04/image-6.png 1006w, https://furushima.com.br/wp-content/uploads/2025/04/image-6-300x143.png 300w, https://furushima.com.br/wp-content/uploads/2025/04/image-6-768x365.png 768w" sizes="(max-width: 1006px) 100vw, 1006px" /></figure>



<p><br><strong>NOMOUNT</strong>: Nesta etapa, o software Oracle lê um arquivo de parâmetros de inicialização, <strong>PFILE</strong> ou <strong>SPFILE</strong>, inicia os processos em segundo plano, aloca memória para a SGA, abre o log de alerta e os arquivos de rastreamento. Uma instância é tipicamente iniciada apenas no modo NOMOUNT durante a criação do banco de dados, durante a recriação de arquivos de controle ou em cenários específicos de backup e recuperação.</p>



<p><br><strong>MOUNT</strong>: Nesta etapa, o software Oracle associa o banco de dados à instância de banco de dados previamente iniciada, abre e lê o controlefile especificado no arquivo de parâmetros de inicialização, <strong>PFILE</strong> ou <strong>SPFILE,</strong> e obtém os nomes e estados dos datafiles e dos redo logs. No entanto, nesta fase, não são realizadas verificações para confirmar a existência dos datafiles e dos redo logs. Iniciar no modo MOUNT para executar algumas operações de manutenção, como renomear datafiles e realizar restore do banco de dados.</p>



<p><br><strong>OPEN</strong>: O software Oracle abre os redo logs e os datafiles de acordo com a lista registrada no controlefile. Inicie no modo OPEN para permitir que os usuários se conectem à instância do banco de dados. Os PDBs não são iniciados por padrão quando você abre o banco de dados.</p>



<p></p>



<h3 class="wp-block-heading">Desligando a instância do banco de dados Oracle</h3>



<p></p>



<p>Às vezes, é necessário desligar a instância do banco de dados (por exemplo, para alterar um parâmetro estático ou aplicar um patch no servidor do banco de dados).</p>



<p>Use o comando SHUTDOWN para desligar a instância do banco de dados, porém há vários modos possívels de se desligar a instância: ABORT, IMMEDIATE, NORMAL e TRANSACTIONAL.</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><tbody><tr><td></td><td>ABORT</td><td>IMMEDIATE</td><td>NORMAL</td><td>TRANSACTIONAL</td></tr><tr><td>Permite novas conexões</td><td>NO</td><td>NO</td><td>NO</td><td>NO</td></tr><tr><td>Espera até que todas as sessões terminem</td><td>NO</td><td>NO</td><td>YES</td><td>NO</td></tr><tr><td>Espera até que todas as transações terminem</td><td>NO</td><td>NO</td><td>YES</td><td>YES</td></tr><tr><td>Força um checkpoint e fecha os todos os arquivos</td><td>NO</td><td>YES</td><td>YES</td><td>YES</td></tr></tbody></table></figure>



<p><br><strong>ABORT</strong>: Se os outros modos de desligamento não funcionarem, você pode usar o modo ABORT. O modo ABORT executa a menor quantidade de trabalho antes de desligar. Como esse modo coloca o banco de dados em um estado inconsistente e requer recuperação antes do reinício, use-o apenas quando necessário. Não é aconselhável fazer backup do banco de dados nesse estado. Geralmente, é usado quando nenhuma outra forma de desligamento funciona, quando há problemas para iniciar a instância do banco de dados ou quando você precisa desligar imediatamente devido a uma situação iminente (como aviso de queda de energia em questão de segundos). O modo ABORT costuma ser o modo de desligamento mais rápido, e o modo NORMAL é o mais lento. Os modos NORMAL e TRANSACTIONAL podem levar muito tempo, dependendo do número de sessões e transações.</p>



<p><br>Durante um desligamento no modo ABORT, uma falha na instância ou um reinício da instância do banco de dados no modo FORCE, o que acontece com o banco de dados:</p>



<ul class="wp-block-list">
<li>As declarações SQL atuais sendo processadas pelo servidor Oracle são imediatamente interrompidas.</li>



<li>O servidor Oracle não espera pelos usuários que estão atualmente conectados ao banco de dados se desconectarem.</li>



<li>Os buffers do banco de dados e de redo não são gravados em disco.</li>



<li>Transações não confirmadas não são revertidas.</li>



<li>A instância é terminada sem fechar os arquivos.</li>



<li>O banco de dados não é fechado ou desmontado.</li>



<li>O próximo reinício requer recuperação da instância, que ocorre automaticamente pelo processo SMON.</li>
</ul>



<p></p>



<p><strong>IMMEDIATE</strong>: Um desligamento no modo <strong>IMMEDIATE</strong> é a opção mais utilizada. • As declarações SQL atuais sendo processadas pela instância do banco de dados não são concluídas. • O servidor de banco de dados não espera pelos usuários que estão atualmente conectados à instância do banco de dados se desconectarem. • O servidor de banco de dados faz rollback das transações ativas e desconecta todos os usuários conectados. • O servidor de banco de dados fecha e desmonta o banco de dados antes de desligar a instância do banco de dados.</p>



<p><strong>NORMAL</strong>: NORMAL é o modo de desligamento padrão se nenhum modo for especificado com o comando SHUTDOWN. • Novas conexões não podem ser feitas. • O servidor Oracle <strong>espera</strong> que todos os usuários se desconectem antes de concluir o desligamento. • Buffers de banco de dados e de redo são gravados em disco. • Processos em segundo plano são terminados e a SGA é removida da memória. • O servidor Oracle fecha e desmonta o banco de dados antes de desligar a instância.</p>



<p><strong>TRANSACTIONAL</strong>: Um desligamento no modo TRANSACTIONAL impede que os clientes percam dados, incluindo resultados de sua atividade atual. • Nenhum cliente pode iniciar uma nova transação nesta instância específica. • Um cliente é desconectado quando o cliente encerra a transação que está em andamento. • Quando todas as transações forem concluídas, ocorre um desligamento imediato.</p>



<figure class="wp-block-image size-full"><img alt="" loading="lazy" decoding="async" width="1017" height="511" src="https://furushima.com.br/wp-content/uploads/2025/04/image-7.png" alt="" class="wp-image-2820" srcset="https://furushima.com.br/wp-content/uploads/2025/04/image-7.png 1017w, https://furushima.com.br/wp-content/uploads/2025/04/image-7-300x151.png 300w, https://furushima.com.br/wp-content/uploads/2025/04/image-7-768x386.png 768w" sizes="(max-width: 1017px) 100vw, 1017px" /></figure>



<p></p>



<h3 class="wp-block-heading">Exemplos práticos:</h3>



<p>Executando apenas o comando <strong>STARTUP</strong> é possível verificar todas as etapas que a instância transita até o estado <strong>OPEN</strong>, onde a base de dados está aberta e pronta para receber conexões:</p>



<figure class="wp-block-image size-full"><img alt="" loading="lazy" decoding="async" width="633" height="283" src="https://furushima.com.br/wp-content/uploads/2025/04/image-8.png" alt="" class="wp-image-2821" srcset="https://furushima.com.br/wp-content/uploads/2025/04/image-8.png 633w, https://furushima.com.br/wp-content/uploads/2025/04/image-8-300x134.png 300w" sizes="(max-width: 633px) 100vw, 633px" /></figure>



<p>É possível escolher a fase de inicialização da instância utilizando as opções <strong>NOMOUNT</strong> ou <strong>MOUNT</strong>:</p>



<p><strong>STARTUP NOMOUNT</strong>, o arquivo de parametros PFILE ou SPFILE será lido e apenas a instância fará a alocação na memória:</p>



<figure class="wp-block-image size-full"><img alt="" loading="lazy" decoding="async" width="610" height="233" src="https://furushima.com.br/wp-content/uploads/2025/04/image-9.png" alt="" class="wp-image-2822" srcset="https://furushima.com.br/wp-content/uploads/2025/04/image-9.png 610w, https://furushima.com.br/wp-content/uploads/2025/04/image-9-300x115.png 300w" sizes="(max-width: 610px) 100vw, 610px" /></figure>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="-- VERIFICAR O STATUS(FASE) DA INSTÂNCIA

SELECT STATUS FROM V$INSTANCE;" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">-- </span><span style="color: #4FC1FF">VERIFICAR</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">O</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">STATUS</span><span style="color: #D4D4D4">(</span><span style="color: #4FC1FF">FASE</span><span style="color: #D4D4D4">) </span><span style="color: #4FC1FF">DA</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">INSTÂNCIA</span></span>
<span class="line"></span>
<span class="line"><span style="color: #4FC1FF">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">STATUS</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">FROM</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">V$INSTANCE</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<p><br>Ao consultar o status da instância, aparecerá</p>



<figure class="wp-block-image size-full"><img alt="" loading="lazy" decoding="async" width="533" height="163" src="https://furushima.com.br/wp-content/uploads/2025/04/image-10.png" alt="" class="wp-image-2823" srcset="https://furushima.com.br/wp-content/uploads/2025/04/image-10.png 533w, https://furushima.com.br/wp-content/uploads/2025/04/image-10-300x92.png 300w" sizes="(max-width: 533px) 100vw, 533px" /></figure>



<p><br>STARTUP MOUNT, o arquivo de parametros PFILE ou SPFILE será lido, a instância iniciará e o controlfile será montado:</p>



<figure class="wp-block-image size-full"><img alt="" loading="lazy" decoding="async" width="626" height="264" src="https://furushima.com.br/wp-content/uploads/2025/04/image-11.png" alt="" class="wp-image-2824" srcset="https://furushima.com.br/wp-content/uploads/2025/04/image-11.png 626w, https://furushima.com.br/wp-content/uploads/2025/04/image-11-300x127.png 300w" sizes="(max-width: 626px) 100vw, 626px" /></figure>



<p><br>Ao consultar o status da instância, aparecerá como MOUNTED:</p>



<figure class="wp-block-image size-full is-resized"><img alt="" loading="lazy" decoding="async" width="542" height="160" src="https://furushima.com.br/wp-content/uploads/2025/04/image-12.png" alt="" class="wp-image-2825" style="width:542px;height:auto" srcset="https://furushima.com.br/wp-content/uploads/2025/04/image-12.png 542w, https://furushima.com.br/wp-content/uploads/2025/04/image-12-300x89.png 300w" sizes="(max-width: 542px) 100vw, 542px" /></figure>



<p><br>SHUTDOWN IMMEDIATE, que é o mais utilizado, ve-se também todas as fases:</p>



<figure class="wp-block-image size-full"><img alt="" loading="lazy" decoding="async" width="478" height="132" src="https://furushima.com.br/wp-content/uploads/2025/04/image-14.png" alt="" class="wp-image-2827" srcset="https://furushima.com.br/wp-content/uploads/2025/04/image-14.png 478w, https://furushima.com.br/wp-content/uploads/2025/04/image-14-300x83.png 300w" sizes="(max-width: 478px) 100vw, 478px" /></figure>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
