<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="generator" content="Asciidoctor 2.0.10"> <meta name="author" content="Perforce Professional Services"> <title>Server Deployment Package (SDP) for Perforce Helix: SDP User Guide (for Unix)</title> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700"> <style> /* Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */ /* Uncomment @import statement to use as custom stylesheet */ /*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/ article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section{display:block} audio,video{display:inline-block} audio:not([controls]){display:none;height:0} html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%} a{background:none} a:focus{outline:thin dotted} a:active,a:hover{outline:0} h1{font-size:2em;margin:.67em 0} abbr[title]{border-bottom:1px dotted} b,strong{font-weight:bold} dfn{font-style:italic} hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0} mark{background:#ff0;color:#000} code,kbd,pre,samp{font-family:monospace;font-size:1em} pre{white-space:pre-wrap} q{quotes:"\201C" "\201D" "\2018" "\2019"} small{font-size:80%} sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline} sup{top:-.5em} sub{bottom:-.25em} img{border:0} svg:not(:root){overflow:hidden} figure{margin:0} fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em} legend{border:0;padding:0} button,input,select,textarea{font-family:inherit;font-size:100%;margin:0} button,input{line-height:normal} button,select{text-transform:none} button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer} button[disabled],html input[disabled]{cursor:default} input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0} button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0} textarea{overflow:auto;vertical-align:top} table{border-collapse:collapse;border-spacing:0} *,*::before,*::after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box} html,body{font-size:100%} body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased} a:hover{cursor:pointer} img,object,embed{max-width:100%;height:auto} object,embed{height:100%} img{-ms-interpolation-mode:bicubic} .left{float:left!important} .right{float:right!important} .text-left{text-align:left!important} .text-right{text-align:right!important} .text-center{text-align:center!important} .text-justify{text-align:justify!important} .hide{display:none} img,object,svg{display:inline-block;vertical-align:middle} textarea{height:auto;min-height:50px} select{width:100%} .center{margin-left:auto;margin-right:auto} .stretch{width:100%} .subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em} div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr} a{color:#2156a5;text-decoration:underline;line-height:inherit} a:hover,a:focus{color:#1d4b8f} a img{border:0} p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility} p aside{font-size:.875em;line-height:1.35;font-style:italic} h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em} h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0} h1{font-size:2.125em} h2{font-size:1.6875em} h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em} h4,h5{font-size:1.125em} h6{font-size:1em} hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0} em,i{font-style:italic;line-height:inherit} strong,b{font-weight:bold;line-height:inherit} small{font-size:60%;line-height:inherit} code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)} ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit} ul,ol{margin-left:1.5em} ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em} ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit} ul.square{list-style-type:square} ul.circle{list-style-type:circle} ul.disc{list-style-type:disc} ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0} dl dt{margin-bottom:.3125em;font-weight:bold} dl dd{margin-bottom:1.25em} abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help} abbr{text-transform:none} blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd} blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)} blockquote cite::before{content:"\2014 \0020"} blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)} blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)} @media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2} h1{font-size:2.75em} h2{font-size:2.3125em} h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em} h4{font-size:1.4375em}} table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede} table thead,table tfoot{background:#f7f8f7} table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left} table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)} table tr.even,table tr.alt{background:#f8f8f7} table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6} h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em} h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400} .clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table} .clearfix::after,.float-group::after{clear:both} :not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed;word-wrap:break-word} :not(pre)>code.nobreak{word-wrap:normal} :not(pre)>code.nowrap{white-space:nowrap} pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed} pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit} pre>code{display:block} pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal} em em{font-style:normal} strong strong{font-weight:400} .keyseq{color:rgba(51,51,51,.8)} kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap} .keyseq kbd:first-child{margin-left:0} .keyseq kbd:last-child{margin-right:0} .menuseq,.menuref{color:#000} .menuseq b:not(.caret),.menuref{font-weight:inherit} .menuseq{word-spacing:-.02em} .menuseq b.caret{font-size:1.25em;line-height:.8} .menuseq i.caret{font-weight:bold;text-align:center;width:.45em} b.button::before,b.button::after{position:relative;top:-1px;font-weight:400} b.button::before{content:"[";padding:0 3px 0 2px} b.button::after{content:"]";padding:0 2px 0 3px} p a>code:hover{color:rgba(0,0,0,.9)} #header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em} #header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table} #header::after,#content::after,#footnotes::after,#footer::after{clear:both} #content{margin-top:1.25em} #content::before{content:none} #header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0} #header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf} #header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px} #header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap} #header .details span:first-child{margin-left:-.125em} #header .details span.email a{color:rgba(0,0,0,.85)} #header .details br{display:none} #header .details br+span::before{content:"\00a0\2013\00a0"} #header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)} #header .details br+span#revremark::before{content:"\00a0|\00a0"} #header #revnumber{text-transform:capitalize} #header #revnumber::after{content:"\00a0"} #content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem} #toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em} #toc>ul{margin-left:.125em} #toc ul.sectlevel0>li>a{font-style:italic} #toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0} #toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none} #toc li{line-height:1.3334;margin-top:.3334em} #toc a{text-decoration:none} #toc a:active{text-decoration:underline} #toctitle{color:#7a2518;font-size:1.2em} @media screen and (min-width:768px){#toctitle{font-size:1.375em} body.toc2{padding-left:15em;padding-right:0} #toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto} #toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em} #toc.toc2>ul{font-size:.9em;margin-bottom:0} #toc.toc2 ul ul{margin-left:0;padding-left:1em} #toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em} body.toc2.toc-right{padding-left:0;padding-right:15em} body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}} @media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0} #toc.toc2{width:20em} #toc.toc2 #toctitle{font-size:1.375em} #toc.toc2>ul{font-size:.95em} #toc.toc2 ul ul{padding-left:1.25em} body.toc2.toc-right{padding-left:0;padding-right:20em}} #content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px} #content #toc>:first-child{margin-top:0} #content #toc>:last-child{margin-bottom:0} #footer{max-width:100%;background:rgba(0,0,0,.8);padding:1.25em} #footer-text{color:rgba(255,255,255,.8);line-height:1.44} #content{margin-bottom:.625em} .sect1{padding-bottom:.625em} @media screen and (min-width:768px){#content{margin-bottom:1.25em} .sect1{padding-bottom:1.25em}} .sect1:last-child{padding-bottom:0} .sect1+.sect1{border-top:1px solid #e7e7e9} #content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400} #content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em} #content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible} #content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none} #content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221} details,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em} details>summary:first-of-type{cursor:pointer;display:list-item;outline:none;margin-bottom:.75em} .admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic} table.tableblock.fit-content>caption.title{white-space:nowrap;width:0} .paragraph.lead>p,#preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)} table.tableblock #preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:inherit} .admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%} .admonitionblock>table td.icon{text-align:center;width:80px} .admonitionblock>table td.icon img{max-width:none} .admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase} .admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6)} .admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0} .exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px} .exampleblock>.content>:first-child{margin-top:0} .exampleblock>.content>:last-child{margin-bottom:0} .sidebarblock{border-style:solid;border-width:1px;border-color:#dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;-webkit-border-radius:4px;border-radius:4px} .sidebarblock>:first-child{margin-top:0} .sidebarblock>:last-child{margin-bottom:0} .sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center} .exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0} .literalblock pre,.listingblock>.content>pre{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;overflow-x:auto;padding:1em;font-size:.8125em} @media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}} @media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}} .literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class="highlight"],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8} .literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)} .listingblock>.content{position:relative} .listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5} .listingblock:hover code[data-lang]::before{display:block} .listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5} .listingblock.terminal pre .command:not([data-prompt])::before{content:"$"} .listingblock pre.highlightjs{padding:0} .listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px} .listingblock pre.prettyprint{border-width:0} .prettyprint{background:#f7f7f8} pre.prettyprint .linenums{line-height:1.45;margin-left:2em} pre.prettyprint li{background:none;list-style-type:inherit;padding-left:0} pre.prettyprint li code[data-lang]::before{opacity:1} pre.prettyprint li:not(:first-child) code[data-lang]::before{display:none} table.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none} table.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal} table.linenotable td.code{padding-left:.75em} table.linenotable td.linenos{border-right:1px solid currentColor;opacity:.35;padding-right:.5em} pre.pygments .lineno{border-right:1px solid currentColor;opacity:.35;display:inline-block;margin-right:.75em} pre.pygments .lineno::before{content:"";margin-right:-.125em} .quoteblock{margin:0 1em 1.25em 1.5em;display:table} .quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em} .quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify} .quoteblock blockquote{margin:0;padding:0;border:0} .quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)} .quoteblock blockquote>.paragraph:last-child p{margin-bottom:0} .quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right} .verseblock{margin:0 1em 1.25em} .verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility} .verseblock pre strong{font-weight:400} .verseblock .attribution{margin-top:1.25rem;margin-left:.5ex} .quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic} .quoteblock .attribution br,.verseblock .attribution br{display:none} .quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)} .quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none} .quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0} .quoteblock.abstract{margin:0 1em 1.25em;display:block} .quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center} .quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf} .quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0} .quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem} .quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;text-align:left;margin-right:0} table.tableblock{max-width:100%;border-collapse:separate} p.tableblock:last-child{margin-bottom:0} td.tableblock>.content>:last-child{margin-bottom:-1.25em} td.tableblock>.content>:last-child.sidebarblock{margin-bottom:0} table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede} table.grid-all>thead>tr>.tableblock,table.grid-all>tbody>tr>.tableblock{border-width:0 1px 1px 0} table.grid-all>tfoot>tr>.tableblock{border-width:1px 1px 0 0} table.grid-cols>*>tr>.tableblock{border-width:0 1px 0 0} table.grid-rows>thead>tr>.tableblock,table.grid-rows>tbody>tr>.tableblock{border-width:0 0 1px} table.grid-rows>tfoot>tr>.tableblock{border-width:1px 0 0} table.grid-all>*>tr>.tableblock:last-child,table.grid-cols>*>tr>.tableblock:last-child{border-right-width:0} table.grid-all>tbody>tr:last-child>.tableblock,table.grid-all>thead:last-child>tr>.tableblock,table.grid-rows>tbody>tr:last-child>.tableblock,table.grid-rows>thead:last-child>tr>.tableblock{border-bottom-width:0} table.frame-all{border-width:1px} table.frame-sides{border-width:0 1px} table.frame-topbot,table.frame-ends{border-width:1px 0} table.stripes-all tr,table.stripes-odd tr:nth-of-type(odd),table.stripes-even tr:nth-of-type(even),table.stripes-hover tr:hover{background:#f8f8f7} th.halign-left,td.halign-left{text-align:left} th.halign-right,td.halign-right{text-align:right} th.halign-center,td.halign-center{text-align:center} th.valign-top,td.valign-top{vertical-align:top} th.valign-bottom,td.valign-bottom{vertical-align:bottom} th.valign-middle,td.valign-middle{vertical-align:middle} table thead th,table tfoot th{font-weight:bold} tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7} tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold} p.tableblock>code:only-child{background:none;padding:0} p.tableblock{font-size:1em} ol{margin-left:1.75em} ul li ol{margin-left:1.5em} dl dd{margin-left:1.125em} dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0} ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em} ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none} ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em} ul.unstyled,ol.unstyled{margin-left:0} ul.checklist{margin-left:.625em} ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em} ul.checklist li>p:first-child>input[type="checkbox"]:first-child{margin-right:.25em} ul.inline{display:-ms-flexbox;display:-webkit-box;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em} ul.inline>li{margin-left:1.25em} .unstyled dl dt{font-weight:400;font-style:normal} ol.arabic{list-style-type:decimal} ol.decimal{list-style-type:decimal-leading-zero} ol.loweralpha{list-style-type:lower-alpha} ol.upperalpha{list-style-type:upper-alpha} ol.lowerroman{list-style-type:lower-roman} ol.upperroman{list-style-type:upper-roman} ol.lowergreek{list-style-type:lower-greek} .hdlist>table,.colist>table{border:0;background:none} .hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none} td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em} td.hdlist1{font-weight:bold;padding-bottom:1.25em} .literalblock+.colist,.listingblock+.colist{margin-top:-.5em} .colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top} .colist td:not([class]):first-child img{max-width:none} .colist td:not([class]):last-child{padding:.25em 0} .thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd} .imageblock.left{margin:.25em .625em 1.25em 0} .imageblock.right{margin:.25em 0 1.25em .625em} .imageblock>.title{margin-bottom:0} .imageblock.thumb,.imageblock.th{border-width:6px} .imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em} .image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0} .image.left{margin-right:.625em} .image.right{margin-left:.625em} a.image{text-decoration:none;display:inline-block} a.image object{pointer-events:none} sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super} sup.footnote a,sup.footnoteref a{text-decoration:none} sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline} #footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em} #footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0} #footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em} #footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em} #footnotes .footnote:last-of-type{margin-bottom:0} #content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0} .gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0} .gist .file-data>table td.line-data{width:99%} div.unbreakable{page-break-inside:avoid} .big{font-size:larger} .small{font-size:smaller} .underline{text-decoration:underline} .overline{text-decoration:overline} .line-through{text-decoration:line-through} .aqua{color:#00bfbf} .aqua-background{background:#00fafa} .black{color:#000} .black-background{background:#000} .blue{color:#0000bf} .blue-background{background:#0000fa} .fuchsia{color:#bf00bf} .fuchsia-background{background:#fa00fa} .gray{color:#606060} .gray-background{background:#7d7d7d} .green{color:#006000} .green-background{background:#007d00} .lime{color:#00bf00} .lime-background{background:#00fa00} .maroon{color:#600000} .maroon-background{background:#7d0000} .navy{color:#000060} .navy-background{background:#00007d} .olive{color:#606000} .olive-background{background:#7d7d00} .purple{color:#600060} .purple-background{background:#7d007d} .red{color:#bf0000} .red-background{background:#fa0000} .silver{color:#909090} .silver-background{background:#bcbcbc} .teal{color:#006060} .teal-background{background:#007d7d} .white{color:#bfbfbf} .white-background{background:#fafafa} .yellow{color:#bfbf00} .yellow-background{background:#fafa00} span.icon>.fa{cursor:default} a span.icon>.fa{cursor:inherit} .admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default} .admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c} .admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111} .admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900} .admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400} .admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000} .conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold} .conum[data-value] *{color:#fff!important} .conum[data-value]+b{display:none} .conum[data-value]::after{content:attr(data-value)} pre .conum[data-value]{position:relative;top:-.125em} b.conum *{color:inherit!important} .conum:not([data-value]):empty{display:none} dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility} h1,h2,p,td.content,span.alt{letter-spacing:-.01em} p strong,td.content strong,div.footnote strong{letter-spacing:-.005em} p,blockquote,dt,td.content,span.alt{font-size:1.0625rem} p{margin-bottom:1.25rem} .sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em} .exampleblock>.content{background:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc} .print-only{display:none!important} @page{margin:1.25cm .75cm} @media print{*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important} html{font-size:80%} a{color:inherit!important;text-decoration:underline!important} a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important} a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em} abbr[title]::after{content:" (" attr(title) ")"} pre,blockquote,tr,img,object,svg{page-break-inside:avoid} thead{display:table-header-group} svg{max-width:100%} p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3} h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid} #toc,.sidebarblock,.exampleblock>.content{background:none!important} #toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important} body.book #header{text-align:center} body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em} body.book #header .details{border:0!important;display:block;padding:0!important} body.book #header .details span:first-child{margin-left:0!important} body.book #header .details br{display:block} body.book #header .details br+span::before{content:none!important} body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important} body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always} .listingblock code[data-lang]::before{display:block} #footer{padding:0 .9375em} .hide-on-print{display:none!important} .print-only{display:block!important} .hide-for-print{display:none!important} .show-for-print{display:inherit!important}} @media print,amzn-kf8{#header>h1:first-child{margin-top:1.25rem} .sect1{padding:0!important} .sect1+.sect1{border:0} #footer{background:none} #footer-text{color:rgba(0,0,0,.6);font-size:.9em}} @media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}} </style> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> </head> <body class="book"> <div id="header"> <h1>Server Deployment Package (SDP) for Perforce Helix: SDP User Guide (for Unix)</h1> <div class="details"> <span id="author" class="author">Perforce Professional Services</span><br> <span id="email" class="email"><a href="mailto:consulting@perforce.com">consulting@perforce.com</a></span><br> <span id="revnumber">version v2020.1,</span> <span id="revdate">2020-09-12</span> </div> <div id="toc" class="toc"> <div id="toctitle">Table of Contents</div> <ul class="sectlevel1"> <li><a href="#_preface">Preface</a></li> <li><a href="#_overview">1. Overview</a> <ul class="sectlevel2"> <li><a href="#_using_this_guide">1.1. Using this Guide</a></li> <li><a href="#_getting_the_sdp">1.2. Getting the SDP</a></li> </ul> </li> <li><a href="#_setting_up_the_sdp">2. Setting up the SDP</a> <ul class="sectlevel2"> <li><a href="#_terminology_and_pre_requisites">2.1. Terminology and pre-requisites</a></li> <li><a href="#_volume_layout_and_hardware">2.2. Volume Layout and Hardware</a></li> </ul> </li> <li><a href="#_installing_the_sdp_on_unix_linux">3. Installing the SDP on Unix / Linux</a> <ul class="sectlevel2"> <li><a href="#_initial_setup">3.1. Initial setup</a> <ul class="sectlevel3"> <li><a href="#_use_of_ssl">3.1.1. Use of SSL</a></li> <li><a href="#_configuration_script_mkdirs_cfg">3.1.2. Configuration script mkdirs.cfg</a></li> </ul> </li> <li><a href="#_configuring_automatic_service_start_on_boot">3.2. Configuring (Automatic) Service Start on Boot</a> <ul class="sectlevel3"> <li><a href="#_for_systems_using_systemd">3.2.1. For Systems using systemd</a></li> <li><a href="#_for_older_systems_still_using_init_d">3.2.2. For (older) systems, still using init.d</a></li> <li><a href="#_startingstopping_perforce_server_products">3.2.3. Starting/Stopping Perforce Server Products</a></li> </ul> </li> <li><a href="#_completing_your_server_configuration">3.3. Completing Your Server Configuration</a> <ul class="sectlevel3"> <li><a href="#_validating_your_sdp_installation">3.3.1. Validating your SDP installation</a></li> </ul> </li> <li><a href="#_configuring_protections_file_types_monitoring_and_security">3.4. Configuring protections, file types, monitoring and security</a></li> <li><a href="#_operating_system_configuration">3.5. Operating system configuration</a></li> <li><a href="#_other_server_configurables">3.6. Other server configurables</a></li> <li><a href="#_archiving_configuration_files">3.7. Archiving configuration files</a></li> </ul> </li> <li><a href="#_backup_replication_and_recovery">4. Backup, Replication, and Recovery</a> <ul class="sectlevel2"> <li><a href="#_typical_backup_procedure">4.1. Typical Backup Procedure</a></li> <li><a href="#_planning_for_ha_and_dr">4.2. Planning for HA and DR</a> <ul class="sectlevel3"> <li><a href="#_further_resources">4.2.1. Further Resources</a></li> <li><a href="#_creating_a_failover_replica_for_commit_or_edge_server">4.2.2. Creating a Failover Replica for Commit or Edge Server</a></li> <li><a href="#_what_is_a_failover_replica">4.2.3. What is a Failover Replica?</a></li> <li><a href="#_mandatory_vs_non_mandatory_standbys">4.2.4. Mandatory vs Non-mandatory Standbys</a></li> <li><a href="#_server_host_naming_conventions">4.2.5. Server host naming conventions</a></li> </ul> </li> <li><a href="#_full_one_way_replication">4.3. Full One-Way Replication</a> <ul class="sectlevel3"> <li><a href="#_replication_setup">4.3.1. Replication Setup</a></li> <li><a href="#_replication_setup_for_failover">4.3.2. Replication Setup for Failover</a></li> <li><a href="#_pre_requisites_for_failover">4.3.3. Pre-requisites for Failover</a></li> <li><a href="#_using_mkrep_sh">4.3.4. Using mkrep.sh</a> <ul class="sectlevel4"> <li><a href="#_server_types">4.3.4.1. Server Types</a></li> <li><a href="#_example">4.3.4.2. Example</a></li> <li><a href="#_mkrep_sh_output">4.3.4.3. Mkrep.sh output</a></li> </ul> </li> <li><a href="#_setting_up_a_replica_manually">4.3.5. Setting up a Replica Manually</a></li> </ul> </li> <li><a href="#_recovery_procedures">4.4. Recovery Procedures</a> <ul class="sectlevel3"> <li><a href="#_recovering_a_master_server_from_a_checkpoint_and_journals">4.4.1. Recovering a master server from a checkpoint and journal(s)</a></li> <li><a href="#_recovering_a_replica_from_a_checkpoint">4.4.2. Recovering a replica from a checkpoint</a></li> <li><a href="#_recovering_from_a_tape_backup">4.4.3. Recovering from a tape backup</a></li> <li><a href="#_failover_to_a_replicated_standby_machine">4.4.4. Failover to a replicated standby machine</a></li> </ul> </li> </ul> </li> <li><a href="#_server_upgrades">5. Server Upgrades</a> <ul class="sectlevel2"> <li><a href="#_upgrading_an_existing_sdp_installation">5.1. Upgrading an existing SDP installation</a></li> <li><a href="#_p4d_server_upgrades">5.2. P4D Server upgrades</a></li> <li><a href="#_database_modifications">5.3. Database Modifications</a></li> </ul> </li> <li><a href="#_maximizing_server_performance">6. Maximizing Server Performance</a> <ul class="sectlevel2"> <li><a href="#_ensure_transparent_huge_pages_thp_is_turned_off">6.1. Ensure Transparent Huge Pages (THP) is turned off</a></li> <li><a href="#_putting_server_locks_directory_into_ram">6.2. Putting server.locks directory into RAM</a></li> <li><a href="#_optimizing_the_database_files">6.3. Optimizing the database files</a></li> <li><a href="#_p4v_performance_settings">6.4. P4V Performance Settings</a></li> <li><a href="#_proactive_performance_maintenance">6.5. Proactive Performance Maintenance</a> <ul class="sectlevel3"> <li><a href="#_limiting_large_requests">6.5.1. Limiting large requests</a></li> <li><a href="#_offloading_remote_syncs">6.5.2. Offloading remote syncs</a></li> </ul> </li> </ul> </li> <li><a href="#_tools_and_scripts">7. Tools and Scripts</a> <ul class="sectlevel2"> <li><a href="#_general_sdp_usage">7.1. General SDP Usage</a> <ul class="sectlevel3"> <li><a href="#_linux">7.1.1. Linux</a></li> <li><a href="#_monitoring_sdp_activities">7.1.2. Monitoring SDP activities</a></li> </ul> </li> <li><a href="#_core_scripts">7.2. Core Scripts</a> <ul class="sectlevel3"> <li><a href="#_p4_vars">7.2.1. p4_vars</a></li> <li><a href="#_p4_instance_vars">7.2.2. p4_<instance>.vars</a></li> <li><a href="#_p4master_run">7.2.3. p4master_run</a></li> <li><a href="#_daily_checkpoint_sh">7.2.4. daily_checkpoint.sh</a></li> <li><a href="#_recreate_offline_db_sh">7.2.5. recreate_offline_db.sh</a></li> <li><a href="#_live_checkpoint_sh">7.2.6. live_checkpoint.sh</a></li> <li><a href="#_p4verify_sh">7.2.7. p4verify.sh</a></li> <li><a href="#_p4login">7.2.8. p4login</a></li> <li><a href="#_p4d_instance_init">7.2.9. p4d_<instance>_init</a></li> <li><a href="#_refresh_p4root_from_offline_db_sh">7.2.10. refresh_P4ROOT_from_offline_db.sh</a></li> <li><a href="#_run_if_master_sh">7.2.11. run_if_master.sh</a></li> <li><a href="#_run_if_edge_sh">7.2.12. run_if_edge.sh</a></li> <li><a href="#_run_if_replica_sh">7.2.13. run_if_replica.sh</a></li> <li><a href="#_run_if_masteredgereplica_sh">7.2.14. run_if_master/edge/replica.sh</a></li> </ul> </li> <li><a href="#_more_server_scripts">7.3. More Server Scripts</a> <ul class="sectlevel3"> <li><a href="#_upgrade_sh">7.3.1. upgrade.sh</a></li> <li><a href="#_p4_crontab">7.3.2. p4.crontab</a></li> <li><a href="#_verify_sdp_sh">7.3.3. verify_sdp.sh</a></li> </ul> </li> <li><a href="#_other_scripts_and_files">7.4. Other Scripts and Files</a> <ul class="sectlevel3"> <li><a href="#_backup_functions_sh">7.4.1. backup_functions.sh</a></li> <li><a href="#_broker_rotate_sh">7.4.2. broker_rotate.sh</a></li> <li><a href="#_edge_dump_sh">7.4.3. edge_dump.sh</a></li> <li><a href="#_edge_vars">7.4.4. edge_vars</a></li> <li><a href="#_edge_shelf_replicate_sh">7.4.5. edge_shelf_replicate.sh</a></li> <li><a href="#_load_checkpoint_sh">7.4.6. load_checkpoint.sh</a></li> <li><a href="#_gen_default_broker_cfg_sh">7.4.7. gen_default_broker_cfg.sh</a></li> <li><a href="#_journal_watch_sh">7.4.8. journal_watch.sh</a></li> <li><a href="#_kill_idle_sh">7.4.9. kill_idle.sh</a></li> <li><a href="#_p4d_base">7.4.10. p4d_base</a></li> <li><a href="#_p4broker_base">7.4.11. p4broker_base</a></li> <li><a href="#_p4ftpd_base">7.4.12. p4ftpd_base</a></li> <li><a href="#_p4p_base">7.4.13. p4p_base</a></li> <li><a href="#_p4pcm_pl">7.4.14. p4pcm.pl</a></li> <li><a href="#_p4review_py">7.4.15. p4review.py</a></li> <li><a href="#_p4review2_py">7.4.16. p4review2.py</a></li> <li><a href="#_p4sanity_check_sh">7.4.17. p4sanity_check.sh</a></li> <li><a href="#_p4web_base">7.4.18. p4web_base</a></li> <li><a href="#_p4dstate_sh">7.4.19. p4dstate.sh</a></li> <li><a href="#_ps_functions_sh">7.4.20. ps_functions.sh</a></li> <li><a href="#_purge_revisions_sh">7.4.21. purge_revisions.sh</a></li> <li><a href="#_recover_edge_sh">7.4.22. recover_edge.sh</a></li> <li><a href="#_replica_cleanup_sh">7.4.23. replica_cleanup.sh</a></li> <li><a href="#_replica_status_sh">7.4.24. replica_status.sh</a></li> <li><a href="#_request_replica_checkpoint_sh">7.4.25. request_replica_checkpoint.sh</a></li> <li><a href="#_rotate_journal_sh">7.4.26. rotate_journal.sh</a></li> <li><a href="#_sync_replica_sh">7.4.27. sync_replica.sh</a></li> <li><a href="#_templates_directory">7.4.28. templates directory</a></li> <li><a href="#_update_limits_py">7.4.29. update_limits.py</a></li> </ul> </li> </ul> </li> <li><a href="#_sdp_package_contents">Appendix A: SDP Package Contents</a> <ul class="sectlevel2"> <li><a href="#_volume_layout_and_server_planning">A.1. Volume Layout and Server Planning</a> <ul class="sectlevel3"> <li><a href="#_memory_and_cpu">A.1.1. Memory and CPU</a></li> <li><a href="#_directory_structure_configuration_script_for_linuxunix">A.1.2. Directory Structure Configuration Script for Linux/Unix</a></li> <li><a href="#_p4d_versions_and_links">A.1.3. P4D versions and links</a></li> <li><a href="#_case_insensitive_p4d_on_unix">A.1.4. Case Insensitive P4D on Unix</a></li> </ul> </li> </ul> </li> <li><a href="#_frequently_asked_questionstroubleshooting">Appendix B: Frequently Asked Questions/Troubleshooting</a> <ul class="sectlevel2"> <li><a href="#_journal_out_of_sequence">B.1. Journal out of sequence</a></li> <li><a href="#_unexpected_end_of_file_in_replica_daily_sync">B.2. Unexpected end of file in replica daily sync</a></li> </ul> </li> </ul> </div> </div> <div id="content"> <div class="sect1"> <h2 id="_preface">Preface</h2> <div class="sectionbody"> <div class="paragraph"> <p>The Server Deployment Package (SDP) is the implementation of Perforce’s recommendations for operating and managing a production Perforce Helix Core Version Control System. It is intended to provide the Helix Core administration team with tools to help:</p> </div> <div class="ulist"> <ul> <li> <p>Simplify Management</p> </li> <li> <p>High Availability (HA)</p> </li> <li> <p>Disaster Recovery (DR)</p> </li> <li> <p>Fast and Safe Upgrades</p> </li> <li> <p>Production Focus</p> </li> <li> <p>Best Practice Configurables</p> </li> <li> <p>Optimal Performance, Data Safety, and Simplified Backup</p> </li> </ul> </div> <div class="paragraph"> <p>This guide is intended to provide instructions of setting up the SDP to help provide users of Helix Core with the above benefits.</p> </div> <div class="paragraph"> <p>This guide assumes some familiarity with Perforce and does not duplicate the basic information in the Perforce user documentation. This document only relates to the Server Deployment Package (SDP) all other Helix Core documentation can be found here: <a href="https://www.perforce.com/support/self-service-resources/documentation">Perforce Support Documentation</a></p> </div> <div class="paragraph"> <p><strong>Please Give Us Feedback</strong></p> </div> <div class="paragraph"> <p>Perforce welcomes feedback from our users. Please send any suggestions for improving this document or the SDP to <a href="mailto:consulting@perforce.com">consulting@perforce.com</a>.</p> </div> </div> </div> <div class="sect1"> <h2 id="_overview">1. Overview</h2> <div class="sectionbody"> <div class="paragraph"> <p>The SDP has four main components:</p> </div> <div class="ulist"> <ul> <li> <p>Hardware and storage layout recommendations for Perforce.</p> </li> <li> <p>Scripts to automate critical maintenance activities</p> </li> <li> <p>Scripts to aid the setup and management of replication (including failover for DR/HA)</p> </li> <li> <p>Scripts to assist with routine administration tasks.</p> </li> </ul> </div> <div class="paragraph"> <p>Each of these components is covered, in detail, in this guide.</p> </div> <div class="sect2"> <h3 id="_using_this_guide">1.1. Using this Guide</h3> <div class="paragraph"> <p><a href="#_setting_up_the_sdp">Chapter 2, <em>Setting up the SDP</em></a> describes concepts and re-requisites</p> </div> <div class="paragraph"> <p><a href="#_installing_the_sdp_on_unix_linux">Chapter 3, <em>Installing the SDP on Unix / Linux</em></a> consists of what you need to know to setup Helix Core sever on a Unix platform.</p> </div> <div class="paragraph"> <p><a href="#_backup_replication_and_recovery">Chapter 4, <em>Backup, Replication, and Recovery</em></a> gives information around the Backup, Restoration and Replication of Helix Core, including some guidance on planning for HA (High Availability) and DR (Disaster Recovery)</p> </div> <div class="paragraph"> <p><a href="#_server_upgrades">Chapter 5, <em>Server Upgrades</em></a> also covers upgrades of <code>p4d</code> and related executables as well as the SDP itself.</p> </div> <div class="paragraph"> <p><a href="#_maximizing_server_performance">Chapter 6, <em>Maximizing Server Performance</em></a> covers optimizations and proactive actions.</p> </div> <div class="paragraph"> <p><a href="#_tools_and_scripts">Chapter 7, <em>Tools and Scripts</em></a> covers all the scripts used within the SDP in detail.</p> </div> <div class="paragraph"> <p><a href="#_sdp_package_contents">Appendix A, <em>SDP Package Contents</em></a> address details of the SDP package.</p> </div> <div class="paragraph"> <p><a href="#_frequently_asked_questionstroubleshooting">Appendix B, <em>Frequently Asked Questions/Troubleshooting</em></a> is useful for other questions.</p> </div> </div> <div class="sect2"> <h3 id="_getting_the_sdp">1.2. Getting the SDP</h3> <div class="paragraph"> <p>The SDP is downloaded as a single zipped tar file the latest version can be found at: <a href="https://swarm.workshop.perforce.com/projects/perforce-software-sdp/files/downloads" class="bare">https://swarm.workshop.perforce.com/projects/perforce-software-sdp/files/downloads</a></p> </div> </div> </div> </div> <div class="sect1"> <h2 id="_setting_up_the_sdp">2. Setting up the SDP</h2> <div class="sectionbody"> <div class="paragraph"> <p>This section tells you how to configure the SDP to setup a new Helix Core server. Whilst the standard installation of Helix Core is fully covered in the linke:https://www.perforce.com/perforce/doc.current/manuals/p4sag/Content/P4SAG/Home-p4sag.html[System Administrator Guide] this section covers the details most relevant to the SDP.</p> </div> <div class="paragraph"> <p>The SDP can be installed on multiple server machines, and each server machine can host one or more Helix Core server instances.</p> </div> <div class="paragraph"> <p>The SDP implements a standard logical directory structure which can be implemented fleixbly on lost of different physical hosts.</p> </div> <div class="sect2"> <h3 id="_terminology_and_pre_requisites">2.1. Terminology and pre-requisites</h3> <div class="olist arabic"> <ol class="arabic"> <li> <p>The term <em>server</em> refers to a Helix Core server <em>instance</em>, unless otherwise specified.</p> </li> <li> <p>The term <em>metadata</em> refers to the Helix Core database files</p> </li> <li> <p><em>Instance:</em> a separate Helix Core instantiation using its own p4d daemon/process</p> </li> </ol> </div> <div class="paragraph"> <p><strong>Pre-Requisites:</strong></p> </div> <div class="olist arabic"> <ol class="arabic"> <li> <p>The Helix Core binaries (p4d, p4, p4broker, p4p) have been downloaded (see <a href="#_installing_the_sdp_on_unix_linux">Chapter 3, <em>Installing the SDP on Unix / Linux</em></a>)</p> </li> <li> <p><em>sudo</em> access is required</p> </li> <li> <p>System administrator available for configuration of drives / volumes (especially if on network or SAN or similar)</p> </li> <li> <p>Supported Unix version, currently these versions are fully supported - for other versions please speak with Perforce Support</p> <div class="ulist"> <ul> <li> <p>Ubuntu 16.04 LTS (xenial)</p> </li> <li> <p>Ubuntu 18.04 LTS (bionic)</p> </li> <li> <p>CentOS or Red Hat 6.x</p> </li> <li> <p>CentOS or Red Hat 7.x</p> </li> <li> <p>SUSE Linux Enterprise Server 12</p> </li> </ul> </div> </li> </ol> </div> </div> <div class="sect2"> <h3 id="_volume_layout_and_hardware">2.2. Volume Layout and Hardware</h3> <div class="paragraph"> <p>As can be expected from a version control system, good disk (storage) management is key to maximising data integrity and performance. Perforce recommend using multiple physical volumes for <strong>each</strong> server instance. Using three or four volumes per instance reduces the chance of hardware failure affecting more than one instance. When naming volumes and directories the SDP assumes the "hx" prefix is used to indicate Helix volumes (your own naming conventions/standards can be used instead). For optimal performance on UNIX machines, the XFS file system is recommended but not mandated.</p> </div> <div class="ulist"> <ul> <li> <p></p> <div class="paragraph"> <p><strong>Perforce metadata (database files), 1 or 2 volumes:</strong> Use the fastest volume possible, ideally SSD or RAID 1+0 on a dedicated controller with the maximum cache available on it. These volumes default to <code>/hxmetadata1</code> and <code>/hxmetadata2</code>.</p> </div> <div class="paragraph"> <p>It is fine to have these both pointing to the same physical volume, e.g. <code>/hxmetadata</code>.</p> </div> </li> <li> <p></p> <div class="paragraph"> <p><strong>Journals and logs:</strong> a fast volume, ideally SSD or RAID 1+0 on its own controller with the standard amount of cache on it. This volume is normally called <code>/hxlogs</code> and should usually be backed up.</p> </div> <div class="paragraph"> <p>If a separate logs volume is not available, put the logs on the <code>/hxmetadata1</code> or <code>/hxmetadata</code> volume.</p> </div> </li> <li> <p></p> <div class="paragraph"> <p><strong>Depot data, archive files, scripts, and checkpoints</strong>: Use a large volume, with RAID 5 on its own controller with a standard amount of cache or a SAN or NAS volume (NFS access is fine). This volume is the only volume that <strong>must</strong> be backed up. The SDP backup scripts place the metadata snapshots on this volume.</p> </div> <div class="paragraph"> <p>This volume is normally called <code>/hxdepots</code>.</p> </div> </li> </ul> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> If multiple controllers are not available, put the <code>hxlogs</code> and <code>hxdepots</code> volumes on the same controller. </td> </tr> </table> </div> <div class="admonitionblock important"> <table> <tr> <td class="icon"> <i class="fa icon-important" title="Important"></i> </td> <td class="content"> Do not run anti-virus tools or back up tools against the <code>hxmetadata</code> volume(s) or <code>hxlogs</code> volume(s), because they can interfere with the operation of the Perforce server. </td> </tr> </table> </div> <div class="paragraph"> <p>On Unix/Linux platforms, the SDP will create a "convenience" directory containing links to the volumes for each instance, by default named <code>/p4</code>. The volume layout is shown in <a href="#_sdp_package_contents">Appendix A, <em>SDP Package Contents</em></a>. This convenience directory enables easy access to the different parts of the file system for each instance.</p> </div> <div class="paragraph"> <p>For example:</p> </div> <div class="ulist"> <ul> <li> <p><code>/p4/1/root</code> contains the database files for instance <code>1</code></p> </li> <li> <p><code>/p4/1/logs</code> contains the log files for instance <code>1</code></p> </li> <li> <p><code>/p4/1/bin</code> contains the binaries and scripts for instance <code>1</code></p> </li> <li> <p><code>/p4/common/bin</code> contains the binaries and scripts common to all instances</p> </li> </ul> </div> </div> </div> </div> <div class="sect1"> <h2 id="_installing_the_sdp_on_unix_linux">3. Installing the SDP on Unix / Linux</h2> <div class="sectionbody"> <div class="paragraph"> <p>To install Perforce Server and the SDP, perform the steps laid out below:</p> </div> <div class="ulist"> <ul> <li> <p>Set up a user account, file system, and configuration scripts.</p> </li> <li> <p>Run the configuration script.</p> </li> <li> <p>Start the server and configure the required file structure for the SDP.</p> </li> </ul> </div> <div class="olist arabic arabic"> <ol class="arabic"> <li> <p>If it doesn’t already exist, create a group called <code>perforce</code>:</p> <div class="literalblock"> <div class="content"> <pre>sudo groupadd perforce</pre> </div> </div> </li> <li> <p>Create a user called perforce and set the user’s home directory to <code>/p4</code> on a local disk.</p> <div class="literalblock"> <div class="content"> <pre>sudo useradd -d /p4 -s /bin/bash -m perforce -g perforce</pre> </div> </div> </li> <li> <p>Create or mount the server file system volumes (per layout in previous section)</p> <div class="ulist"> <ul> <li> <p><code>/hxdepots</code></p> </li> <li> <p><code>/hxlogs</code></p> <div class="paragraph"> <p>and either:</p> </div> </li> <li> <p><code>/hxmetadata</code></p> </li> </ul> </div> <div class="paragraph"> <p>or</p> </div> <div class="ulist"> <ul> <li> <p><code>/hxmetadata1</code></p> </li> <li> <p><code>/hxmetadata2</code></p> </li> </ul> </div> </li> <li> <p>These directories should be owned by: <code>perforce:perforce</code></p> <div class="literalblock"> <div class="content"> <pre>sudo chown -R perforce:perforce /hx*</pre> </div> </div> </li> <li> <p>Either download the SDP directly or move the previously downloaded version to <code>/hxdepots</code></p> <div class="literalblock"> <div class="content"> <pre>cd /hxdepots export sdpver=2019.3.26571 # Specify desired latest release wget https://swarm.workshop.perforce.com/downloads/guest/perforce_software/sdp/downloads/sdp.Unix.${sdpver}.tgz</pre> </div> </div> <div class="paragraph"> <p>Or:</p> </div> <div class="literalblock"> <div class="content"> <pre>mv sdp.Unix.${sdpver}.tgz /hxdepots</pre> </div> </div> </li> <li> <p>Untar and uncompress the downloaded sdp files:</p> <div class="literalblock"> <div class="content"> <pre>tar -zxvf sdp.Unix.${sdpver}.tgz</pre> </div> </div> </li> <li> <p>Set environment variable SDP, this makes certain later steps easier.</p> <div class="literalblock"> <div class="content"> <pre>export SDP=/hxdepots/sdp</pre> </div> </div> </li> <li> <p>Make the entire $SDP (<code>/hxdepot/sdp</code>) directory writable:</p> <div class="literalblock"> <div class="content"> <pre>chmod -R +w $SDP</pre> </div> </div> </li> <li> <p>Download the appropriate p4, p4d and p4broker binaries for your release and platform (substituting desired release for <code>r20.1</code> below)</p> <div class="literalblock"> <div class="content"> <pre>cd $SDP/Server/Unix/p4/common/bin wget http://ftp.perforce.com/perforce/r20.1/bin.linux26x86_64/p4 wget http://ftp.perforce.com/perforce/r20.1/bin.linux26x86_64/p4d wget http://ftp.perforce.com/perforce/r20.1/bin.linux26x86_64/p4broker</pre> </div> </div> </li> <li> <p>make them executable</p> <div class="literalblock"> <div class="content"> <pre>chmod +x p4*</pre> </div> </div> </li> </ol> </div> <div class="sect2"> <h3 id="_initial_setup">3.1. Initial setup</h3> <div class="paragraph"> <p>The next steps highlight the setup and configuration of a new Helix Core instance using the SDP.</p> </div> <div class="olist arabic"> <ol class="arabic"> <li> <p>cd to <code>$SDP/Server/Unix/setup</code> and copy <code>mkdirs.cfg</code> to an instance specific version such as <code>mkdirs.1.cfg</code> and edit it, information on the variables can be found in <a href="#_configuration_script_mkdirs_cfg">Section 3.1.2, “Configuration script mkdirs.cfg”</a> of this document.</p> <div class="paragraph"> <p>Example:</p> </div> <div class="literalblock"> <div class="content"> <pre>cd $SDP/Server/Unix/setup cp mkdirs.cfg mkdirs.1.cfg vi mkdirs.1.cfg</pre> </div> </div> <div class="paragraph"> <p>Set the following:</p> </div> <div class="literalblock"> <div class="content"> <pre>P4ADMINPASS=******** MAILFROM=perforceadmin@myDomain.com MAILHOST=myMailServer.myDomain.com P4DNSNAME=thisMachine.myDomain.com P4SERVICEPASS=******** MASTER_ID=myName.${SDP_INSTANCE}</pre> </div> </div> </li> <li> <p>As the root user (or sudo), run this:</p> <div class="literalblock"> <div class="content"> <pre>mkdirs.sh <instance number/name></pre> </div> </div> <div class="paragraph"> <p>e.g.</p> </div> <div class="literalblock"> <div class="content"> <pre>mkdirs.sh 1 mkdirs.sh perfmain</pre> </div> </div> </li> </ol> </div> <div class="admonitionblock important"> <table> <tr> <td class="icon"> <i class="fa icon-important" title="Important"></i> </td> <td class="content"> If you use a "name" for the instance (not an integer) you MUST modify the P4PORT variable in <code>mkdirs.cfg</code> </td> </tr> </table> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> instance must map to the name of the cfg file or the default file will be used with potentially unexpected results. </td> </tr> </table> </div> <div class="paragraph"> <p>e.g. <code>mkdirs.sh 1</code> requires <code>mkdirs.1.cfg</code>, or <code>mkdirs.sh lon</code> requires <code>mkdirs.lon.cfg</code></p> </div> <div class="olist arabic"> <ol class="arabic" start="3"> <li> <p>Put the Perforce license file for the server into <code>/p4/1/root</code></p> </li> </ol> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> if you have multiple instances and have been provided with port-specific licenses by Perforce, the appropriate license file must be stored in the appropriate <code>/p4/<instance>/root</code> folder. </td> </tr> </table> </div> <div class="admonitionblock important"> <table> <tr> <td class="icon"> <i class="fa icon-important" title="Important"></i> </td> <td class="content"> the license file must be renamed to <code>license</code> </td> </tr> </table> </div> <div class="paragraph"> <p>Your Helix Core instance is now setup, but not running. The next steps detail how to make the Helix Core server a system service.</p> </div> <div class="paragraph"> <p>You are then free to start up the <code>p4d</code> instance as documented <a href="#_startingstopping_perforce_server_products">Section 3.2.3, “Starting/Stopping Perforce Server Products”</a></p> </div> <div class="paragraph"> <p>Please note that if you have configured SSL, then refer to <a href="#_use_of_ssl">Section 3.1.1, “Use of SSL”</a></p> </div> <div class="sect3"> <h4 id="_use_of_ssl">3.1.1. Use of SSL</h4> <div class="paragraph"> <p>As documented in the comments in mkdirs.cfg, if you are planning to use SSL you need to set the value of:</p> </div> <div class="literalblock"> <div class="content"> <pre>SSL_PREFIX=ssl:</pre> </div> </div> <div class="paragraph"> <p>Then you need to put certificates in <code>/p4/ssl</code> after the SDP install or you can generate a self signed certificate as follows:</p> </div> <div class="paragraph"> <p>Edit <code>/p4/ssl/config.txt</code> to put in the info for your company. Then run:</p> </div> <div class="literalblock"> <div class="content"> <pre>/p4/common/bin/p4master_run <instance> /p4/<instance>/p4d_<instance> -Gc</pre> </div> </div> <div class="paragraph"> <p>For example using instance 1:</p> </div> <div class="literalblock"> <div class="content"> <pre>/p4/common/bin/p4master_run 1 /p4/1/bin/p4d_1 -Gc</pre> </div> </div> <div class="paragraph"> <p>In order to validate that SSL is working correctly:</p> </div> <div class="literalblock"> <div class="content"> <pre>source /p4/common/bin/p4_vars 1</pre> </div> </div> <div class="paragraph"> <p>Check that P4TRUST is appropriately set in the output of:</p> </div> <div class="literalblock"> <div class="content"> <pre>p4 set</pre> </div> </div> <div class="paragraph"> <p>Update the P4TRUST values (answer yes when prompted - the second command uses the value of the <code>hostname</code> command):</p> </div> <div class="literalblock"> <div class="content"> <pre>p4 -p ssl:1666 trust</pre> </div> </div> <div class="literalblock"> <div class="content"> <pre>p4 -p ssl:`hostname`:1666 trust</pre> </div> </div> <div class="paragraph"> <p>Check the stored P4TRUST values:</p> </div> <div class="literalblock"> <div class="content"> <pre>p4 trust -l</pre> </div> </div> <div class="paragraph"> <p>Check you are not prompted for trust:</p> </div> <div class="literalblock"> <div class="content"> <pre>p4 login p4 info</pre> </div> </div> </div> <div class="sect3"> <h4 id="_configuration_script_mkdirs_cfg">3.1.2. Configuration script mkdirs.cfg</h4> <div class="paragraph"> <p>The <code>mkdirs.sh</code> script executed above resides in <code>$SDP/Server/Unix/setup</code>. It sets up the basic directory structure used by the SDP. Carefully review the config file <code>mkdirs.<strong><em>instance</em></strong>.cfg</code> for this script before running it, and adjust the values of the variables as required. The important parameters are:</p> </div> <table class="tableblock frame-all grid-all stretch"> <colgroup> <col style="width: 50%;"> <col style="width: 50%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-top">Parameter</th> <th class="tableblock halign-left valign-top">Description</th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">DB1</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Name of the hxmetadata1 volume (can be same as DB2)</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">DB2</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Name of the hxmetadata2 volume (can be same as DB1)</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">DD</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Name of the hxdepots volume</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">LG</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Name of the hxlogs volume</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">CN</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Volume for /p4/common</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">SDP</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Path to SDP distribution file tree</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">SHAREDDATA</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">TRUE or FALSE - whether sharing the /hxdepots volume with a replica - normally this is FALSE</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">ADMINUSER</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">P4USER value of a Perforce super user that operates SDP scripts, typically perforce or p4admin.</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">OSUSER</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Operating system user that will run the Perforce instance, typically perforce.</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">OSGROUP</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Operating system group that OSUSER belongs to, typically perforce.</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">CASE_SENSITIVE</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Indicates if server has special case sensitivity settings</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">SSL_PREFIX</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Set if SSL is required so either "ssl:" or blank for no SSL</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"> <p>P4ADMINPASS</p> </div> <div class="paragraph"> <p>P4SERVICEPASS</p> </div></div></td> <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"> <p>Password to use for Perforce superuser account - can be edited later in /p4/common/config/.p4password.p4_1.admin</p> </div> <div class="paragraph"> <p>Service User’s password for replication - can be edited later - same dir as above.</p> </div></div></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">P4DNSNAME</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Fully qualified DNS name of the Perforce master server machine</p></td> </tr> </tbody> </table> <div class="paragraph"> <p>For a detailed description of this config file it is fully documented with in-file comments, or see</p> </div> </div> </div> <div class="sect2"> <h3 id="_configuring_automatic_service_start_on_boot">3.2. Configuring (Automatic) Service Start on Boot</h3> <div class="paragraph"> <p>You normally want to configure your host such that the Helix Core Server (and/or Proxy or Broker) will autostart when the machine boots.</p> </div> <div class="paragraph"> <p>This is done using Systemd or Init scripts as covered below.</p> </div> <div class="sect3"> <h4 id="_for_systems_using_systemd">3.2.1. For Systems using systemd</h4> <div class="paragraph"> <p>RHEL 7 or 8, CentOS 7 or 8, SuSE 12, Ubuntu (>= v16.04) (and other) distributions utilize <strong>systemd / systemctl</strong> as the mechanism for controlling services, replacing the earlier init process. At present mkdirs.sh does <strong>not</strong> generate the systemd configuration file(s) automatically, but a sample is included in the SDP distribution in (<code>$SDP/Server/Unix/setup/systemd</code>), along with a README.md file that describes the configuration process, including for multiple instances.</p> </div> <div class="paragraph"> <p>We recommend that you give the OS user (perforce) sudo access, so that it can run the commands below prefixing them with sudo.</p> </div> <div class="paragraph"> <p>For simple installation run these commands as the root user (or prefix with <code>sudo</code>):</p> </div> <div class="literalblock"> <div class="content"> <pre>cp $SDP/Server/Unix/setup/system/p4d_1.system /etc/systemd/system/ sudo systemctl enable p4d_1</pre> </div> </div> <div class="paragraph"> <p>|The above enables service for auto-start on boot. The following show management commands:</p> </div> <div class="literalblock"> <div class="content"> <pre>sudo systemctl status p4d_1 sudo systemctl start p4d_1 sudo systemctl stop p4d_1</pre> </div> </div> <div class="admonitionblock important"> <table> <tr> <td class="icon"> <i class="fa icon-important" title="Important"></i> </td> <td class="content"> If you are using <code>systemd</code> and you have configured <code>systemctl</code> services, then it is vital you ALWAYS use <code>systemctl</code> to start/stop etc. Otherwise you risk database corruption if <code>systemd</code> does not think the service is running when it actually is running (for example - on shutdown <code>systemd</code> will just kill processes without doing it cleanly and waiting for them, because it thinks the service is not running). </td> </tr> </table> </div> </div> <div class="sect3"> <h4 id="_for_older_systems_still_using_init_d">3.2.2. For (older) systems, still using init.d</h4> <div class="paragraph"> <p>The <code>mkdirs.sh</code> script creates a set of startup scripts in the instance-specific bin folder:</p> </div> <div class="literalblock"> <div class="content"> <pre>/p4/1/bin/p4d_1_init /p4/1/bin/p4broker_1_init # only created if a p4broker executable found /p4/1/bin/p4p_1_init # only created if a p4p executable found</pre> </div> </div> <div class="paragraph"> <p>Run these commands as the root user (or sudo): Repeat this step for all init scripts you wish to add.</p> </div> <div class="literalblock"> <div class="content"> <pre>cd /etc/init.d ln -s /p4/1/bin/p4d_1_init chkconfig --add p4d_1_init chkconfig p4d_1_init on</pre> </div> </div> </div> <div class="sect3"> <h4 id="_startingstopping_perforce_server_products">3.2.3. Starting/Stopping Perforce Server Products</h4> <div class="paragraph"> <p>The SDP includes templates for initialization (start/stop) scripts, "init scripts," for a variety of Perforce server products, including:</p> </div> <div class="ulist"> <ul> <li> <p>p4d</p> </li> <li> <p>p4broker</p> </li> <li> <p>p4p</p> </li> <li> <p>p4dtg</p> </li> <li> <p>p4ftpd</p> </li> <li> <p>p4web</p> </li> </ul> </div> <div class="paragraph"> <p>The init scripts are named <code>/p4/<instance>/bin/<service>_<instance>_init</code>, e.g. <code>/p4/1/bin/p4d_1_init</code> or <code>/p4/1/bin/p4broker_1_init</code>.</p> </div> <div class="paragraph"> <p>For example, the init script for starting p4d for Instance 1 is <code>/p4/1/bin/p4d_1_init</code>. All init scripts accept at least start, stop, and status arguments. The perforce user can start p4d by calling:</p> </div> <div class="literalblock"> <div class="content"> <pre>p4d_1_init start</pre> </div> </div> <div class="paragraph"> <p>And stop it by calling:</p> </div> <div class="literalblock"> <div class="content"> <pre>p4d_1_init stop</pre> </div> </div> <div class="paragraph"> <p>Once logged into Perforce as a super user, the p4 admin stop command can also be used to stop p4d.</p> </div> <div class="paragraph"> <p>All init scripts can be started as the perforce user or the root user (except p4web, which must start initially as root). The application runs as the perforce user in any case. If the init scripts are configured as system services (non-systemd distributions), they can also be called by the root user using the service command, as in this example to start p4d:</p> </div> <div class="literalblock"> <div class="content"> <pre>service p4d_1_init start</pre> </div> </div> <div class="paragraph"> <p>Templates for the init scripts used by <code>mkdirs.sh</code> are stored in:</p> </div> <div class="literalblock"> <div class="content"> <pre>/p4/common/etc/init.d</pre> </div> </div> <div class="paragraph"> <p>There are also basic crontab templates for a Perforce master and replica server in:</p> </div> <div class="literalblock"> <div class="content"> <pre>/p4/common/etc/cron.d</pre> </div> </div> <div class="paragraph"> <p>These define schedules for routine checkpoint operations, replica status checks, and email reviews.</p> </div> <div class="paragraph"> <p>The Perforce should have a super user defined as named by the P4USER setting in mkdir.</p> </div> <div class="paragraph"> <p>To configure and start instance 1, follow these steps:</p> </div> <div class="olist arabic"> <ol class="arabic"> <li> <p>Start the Perforce server by calling</p> <div class="literalblock"> <div class="content"> <pre>p4d_1_init start</pre> </div> </div> <div class="paragraph"> <p>or use <code>sudo systemctl start p4d_1</code> if using <code>sytemd</code></p> </div> </li> </ol> </div> </div> </div> <div class="sect2"> <h3 id="_completing_your_server_configuration">3.3. Completing Your Server Configuration</h3> <div class="olist arabic"> <ol class="arabic"> <li> <p>Ensure that the admin user configured above has the correct password defined in <code>/p4/common/config/.p4passwd.p4_1.admin</code>, and then run the p4login script (which calls the p4 login command using the <code>.p4passwd.p4_1.admin</code> file)</p> </li> <li> <p>For new servers, run this script, which sets several recommended configurables:</p> <div class="literalblock"> <div class="content"> <pre>$SDP/Server/setup/configure_new_server.sh 1</pre> </div> </div> </li> </ol> </div> <div class="paragraph"> <p>For existing servers, examine this file, and manually apply the p4 configure command to set configurables on your Perforce server.</p> </div> <div class="paragraph"> <p>Initialize the perforce user’s crontab with one of these commands:</p> </div> <div class="literalblock"> <div class="content"> <pre>crontab /p4/p4.crontab</pre> </div> </div> <div class="paragraph"> <p>and customise execution times for the commands within the crontab files to suite the specific installation.</p> </div> <div class="paragraph"> <p>The SDP uses wrapper scripts in the crontab: <code>run_if_master.sh</code>, <code>run_if_edge.sh</code>, <code>run_if_replica.sh</code>. We suggest you ensure these are working as desired, e.g.</p> </div> <div class="literalblock"> <div class="content"> <pre>/p4/common/bin/run_if_master.sh 1 echo yes /p4/common/bin/run_if_replica.sh 1 echo yes /p4/common/bin/run_if_edge.sh 1 echo yes</pre> </div> </div> <div class="paragraph"> <p>The above should output <code>yes</code> if you are on the master (commit) machine (or replica/edge as appropriate), but otherwise nothing. Any issues with the above indicate incorrect values for <code>$MASTER_ID</code>, or for other values within <code>/p4/common/config/p4_1.vars</code> (assuming instance <code>1</code>). You can debug this with:</p> </div> <div class="literalblock"> <div class="content"> <pre>bash -xv /p4/common/bin/run_if_master.sh 1 echo yes</pre> </div> </div> <div class="paragraph"> <p>If in doubt contact support.</p> </div> <div class="sect3"> <h4 id="_validating_your_sdp_installation">3.3.1. Validating your SDP installation</h4> <div class="paragraph"> <p>Source your SDP environment variables and check that they look appropriate - for <instance> <code>1</code>:</p> </div> <div class="literalblock"> <div class="content"> <pre>source /p4/common/bin/p4_vars 1</pre> </div> </div> <div class="paragraph"> <p>The output of <code>p4 set</code> should be something like:</p> </div> <div class="literalblock"> <div class="content"> <pre>P4CONFIG=/p4/1/.p4config (config 'noconfig') P4ENVIRO=/dev/null/.p4enviro P4JOURNAL=/p4/1/logs/journal P4LOG=/p4/1/logs/log P4PCACHE=/p4/1/cache P4PORT=ssl:1666 P4ROOT=/p4/1/root P4SSLDIR=/p4/ssl P4TICKETS=/p4/1/.p4tickets P4TRUST=/p4/1/.p4trust P4USER=perforce</pre> </div> </div> <div class="paragraph"> <p>There is a script <code>/p4/common/bin/verify_sdp.sh</code>. Run this specifying the <instance> id, e.g.</p> </div> <div class="literalblock"> <div class="content"> <pre>/p4/common/bin/verify_sdp.sh 1</pre> </div> </div> <div class="paragraph"> <p>The output should be something like:</p> </div> <div class="literalblock"> <div class="content"> <pre>verify_sdp.sh v5.6.1 Starting SDP verification on host helixcorevm1 at Fri 2020-08-14 17:02:45 UTC with this command line: /p4/common/bin/verify_sdp.sh 1</pre> </div> </div> <div class="literalblock"> <div class="content"> <pre>If you have any questions about the output from this script, contact support@perforce.com. ------------------------------------------------------------------------------ Doing preflight sanity checks. Preflight Check: Ensuring these utils are in PATH: date ls grep awk id head tail Verified: Essential tools are in the PATH. Preflight Check: cd /p4/common/bin Verified: cd works to: /p4/common/bin Preflight Check: Checking current user owns /p4/common/bin Verified: Current user [perforce] owns /p4/common/bin Preflight Check: Checking /p4 and /p4/<instance> are local dirs. Verified: P4HOME has expected value: /p4/1 Verified: This P4HOME path is not a symlink: /p4/1 Verified: cd to /p4 OK. Verified: Dir /p4 is a local dir. Verified: cd to /p4/1 OK. Verified: P4HOME dir /p4/1 is a local dir.</pre> </div> </div> <div class="paragraph"> <p>Finishing with:</p> </div> <div class="literalblock"> <div class="content"> <pre>Verifications completed, with 0 errors and 0 warnings detected in 57 checks.</pre> </div> </div> <div class="paragraph"> <p>If it mentions something like:</p> </div> <div class="literalblock"> <div class="content"> <pre>Verifications completed, with 2 errors and 1 warnings detected in 57 checks.</pre> </div> </div> <div class="paragraph"> <p>then review the details. If in doubt contact <a href="mailto:support@perforce.com">support@perforce.com</a></p> </div> </div> </div> <div class="sect2"> <h3 id="_configuring_protections_file_types_monitoring_and_security">3.4. Configuring protections, file types, monitoring and security</h3> <div class="paragraph"> <p>After the server is installed and configured, most sites will want to modify server permissions (protections) and security settings. Other common configuration steps include modifying the file type map and enabling process monitoring. To configure permissions, perform the following steps:</p> </div> <div class="olist arabic"> <ol class="arabic"> <li> <p>To set up protections, issue the <code>p4 protect</code> command. The protections table is displayed.</p> </li> <li> <p>Delete the following line:</p> <div class="literalblock"> <div class="content"> <pre>write user * * //depot/...</pre> </div> </div> </li> <li> <p>Define protections for your server using groups. Perforce uses an inclusionary model. No access is given by default, you must specifically grant access to users/groups in the protections table. It is best for performance to grant users specific access to the areas of the depot that they need rather than granting everyone open access, and then trying to remove access via exclusionary mappings in the protect table even if that means you end up generating a larger protect table.</p> </li> <li> <p>To set the server’s default file types, run the p4 typemap command and define typemap entries to override Perforce’s default behavior.</p> </li> <li> <p>Add any file type entries that are specific to your site. Suggestions:</p> <div class="ulist"> <ul> <li> <p>For already-compressed file types (such as <code>.zip</code>, <code>.gz</code>, <code>.avi</code>, <code>.gif</code>), assign a file type of <code>binary+Fl</code> to prevent the server from attempting to compress them again before storing them.</p> </li> <li> <p>For regular binary files, add <code>binary+l</code> to make so that only one person at a time can check them out.</p> </li> </ul> </div> <div class="paragraph"> <p>A sample file is provided in <code>$SDP/Server/config/typemap</code></p> </div> </li> </ol> </div> <div class="paragraph"> <p>If you are doing things like games development with <code>Unreal Engine</code> or <code>Unity</code>, then there are specific recommended typemaps to add in KB articles: <a href="https://community.perforce.com/s/">Search the Knowledge Base</a></p> </div> <div class="olist arabic"> <ol class="arabic"> <li> <p>To make your changelists default to restricted (for high security environments):</p> <div class="literalblock"> <div class="content"> <pre>p4 configure set defaultChangeType=restricted</pre> </div> </div> </li> </ol> </div> </div> <div class="sect2"> <h3 id="_operating_system_configuration">3.5. Operating system configuration</h3> <div class="paragraph"> <p>Check <a href="#_maximizing_server_performance">Chapter 6, <em>Maximizing Server Performance</em></a> for detailed recommendations.</p> </div> </div> <div class="sect2"> <h3 id="_other_server_configurables">3.6. Other server configurables</h3> <div class="paragraph"> <p>There are various configurables that you should consider setting for your server.</p> </div> <div class="paragraph"> <p>Some suggestions are in the file: <code>$SDP/Server/setup/configure_new_server.sh</code></p> </div> <div class="paragraph"> <p>Review the contents and either apply individual settings manually, or edit the file and apply the newly edited version. If you have any questions, please see the <a href="https://www.perforce.com/manuals/cmdref/Content/CmdRef/configurables.configurables.html">configurables section in Command Reference Guide appendix</a> (get the right version for your server!). You can also contact support regarding questions.</p> </div> </div> <div class="sect2"> <h3 id="_archiving_configuration_files">3.7. Archiving configuration files</h3> <div class="paragraph"> <p>Now that the server is running properly, copy the following configuration files to the hxdepots volume for backup:</p> </div> <div class="ulist"> <ul> <li> <p>Any init scripts used in <code>/etc/init.d</code> or any systemd scripts to <code>/etc/systemd/system</code></p> </li> <li> <p>A copy of the crontab file, obtained using <code>crontab -l</code>.</p> </li> <li> <p>Any other relevant configuration scripts, such as cluster configuration scripts, failover scripts, or disk failover configuration files.</p> </li> </ul> </div> </div> </div> </div> <div class="sect1"> <h2 id="_backup_replication_and_recovery">4. Backup, Replication, and Recovery</h2> <div class="sectionbody"> <div class="paragraph"> <p>Perforce servers maintain <em>metadata</em> and <em>versioned files</em>. The metadata contains all the information about the files in the depots. Metadata resides in database (db.*) files in the server’s root directory (P4ROOT). The versioned files contain the file changes that have been submitted to the server. Versioned files reside on the hxdepots volume.</p> </div> <div class="paragraph"> <p>This section assumes that you understand the basics of Perforce backup and recovery. For more information, consult the Perforce <a href="https://www.perforce.com/perforce/doc.current/manuals/p4sag/Content/P4SAG/chapter.backup.html">System Administrator’s Guide</a> and <a href="https://www.perforce.com/perforce/doc.current/manuals/p4sag/Content/P4SAG/failover.html#Failover">failover</a>.</p> </div> <div class="sect2"> <h3 id="_typical_backup_procedure">4.1. Typical Backup Procedure</h3> <div class="paragraph"> <p>The SDP’s maintenance scripts, run as <code>cron</code> tasks, periodically back up the metadata. The weekly sequence is described below.</p> </div> <div class="paragraph"> <p><strong>Seven nights a week, perform the following tasks:</strong></p> </div> <div class="olist arabic"> <ol class="arabic"> <li> <p>Truncate the active journal.</p> </li> <li> <p>Replay the journal to the offline database. (Refer to Figure 2: SDP Runtime Structure and Volume Layout for more information on the location of the live and offline databases.)</p> </li> <li> <p>Create a checkpoint from the offline database.</p> </li> <li> <p>Recreate the offline database from the last checkpoint.</p> </li> </ol> </div> <div class="paragraph"> <p><strong>Once a week, perform the following tasks:</strong></p> </div> <div class="olist arabic"> <ol class="arabic"> <li> <p>Verify all depot files.</p> </li> </ol> </div> <div class="paragraph"> <p><strong>Once every few months, perform the following tasks:</strong></p> </div> <div class="olist arabic"> <ol class="arabic"> <li> <p>Stop the live server.</p> </li> <li> <p>Truncate the active journal.</p> </li> <li> <p>Replay the journal to the offline database. (Refer to Figure 2: SDP Runtime Structure and Volume Layout for more information on the location of the live and offline databases.)</p> </li> <li> <p>Archive the live database.</p> </li> <li> <p>Move the offline database to the live database directory.</p> </li> <li> <p>Start the live server.</p> </li> <li> <p>Create a new checkpoint from the archive of the live database.</p> </li> <li> <p>Recreate the offline database from the last checkpoint.</p> </li> <li> <p>Verify all depots.</p> </li> </ol> </div> <div class="paragraph"> <p>This normal maintenance procedure puts the checkpoints (metadata snapshots) on the hxdepots volume, which contains the versioned files. Backing up the hxdepots volume with a normal backup utility like <em>robocopy</em> or <em>rsync</em> provides you with all the data necessary to recreate the server.</p> </div> <div class="paragraph"> <p>To ensure that the backup does not interfere with the metadata backups (checkpoints), coordinate backup of the hxdepots volume using the SDP maintenance scripts.</p> </div> <div class="paragraph"> <p>The preceding maintenance procedure minimizes server downtime, because checkpoints are created from offline or saved databases while the server is running.</p> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> With no additional configuration, the normal maintenance prevents loss of more than one day’s metadata changes. To provide an optimal <a href="http://en.wikipedia.org/wiki/Recovery_point_objective">Recovery Point Objective</a> (RPO), the SDP provides additional tools for replication. </td> </tr> </table> </div> </div> <div class="sect2"> <h3 id="_planning_for_ha_and_dr">4.2. Planning for HA and DR</h3> <div class="paragraph"> <p>The concepts for HA (High Availability) and DR (Disaster Recovery) are fairly similar - they are both types of Helix Core replica.</p> </div> <div class="paragraph"> <p>When you have servers with Services of <code>commit-server</code>, <code>standard</code>, or <code>edge-server</code> - see <a href="https://www.perforce.com/perforce/doc.current/manuals/p4sag/Content/P4SAG/deployment-architecture.html">deployment architectures</a> you should consider your requirements for how to recover from a failure to any such servers.</p> </div> <div class="paragraph"> <p>See also <a href="https://community.perforce.com/s/article/5434">Replica types and use cases</a></p> </div> <div class="paragraph"> <p>The key issues are around ensuring that you have have appropriate values for the following measures for your Helix Core installation:</p> </div> <div class="ulist"> <ul> <li> <p>RTO - Recovery Time Objective - how long will it take you to recover to a backup?</p> </li> <li> <p>RPO - Recovery Point Objective - how much data are you prepared to risk losing if you have to failover to a backup server?</p> </li> </ul> </div> <div class="paragraph"> <p>We need to consider planned vs unplanned failover. Planned may be due to upgrading the core Operating System or some other dependency in your infrastructure, or a similar activity.</p> </div> <div class="paragraph"> <p>Unplanned covers risks you are seeking to mitigate with failover:</p> </div> <div class="ulist"> <ul> <li> <p>loss of a machine, or some machine related hardware failure (e.g. network)</p> </li> <li> <p>loss of a VM cluster</p> </li> <li> <p>failure of storage</p> </li> <li> <p>loss of a data center or machine room</p> </li> <li> <p>etc…​</p> </li> </ul> </div> <div class="paragraph"> <p>So, if your main <code>commit-server</code> fails, how fast should be you be able to be up and running again, and how much data might you be prepared to lose? What is the potential disruption to your organisation if the Helix Core repository is down? How many people would be impacted in some way?</p> </div> <div class="paragraph"> <p>You also need to consider the costs of your mitigation strategies. For example, this can range from:</p> </div> <div class="ulist"> <ul> <li> <p>taking a backup once per 24 hours and requiring maybe an hour or two to restore it. Thus you might lose up to 24 hours of work for an unplanned failure, and require several hours to restore.</p> </li> <li> <p>having a high availability replica which is a mirror of the server hardware and ready to take over within minutes if required</p> </li> </ul> </div> <div class="paragraph"> <p>Having a replica for HA or DR is likely to reduce your RPO and RTO to well under an hour (<10 minutes if properly prepared for) - at the cost of the resources to run such a replica, and the management overhead to monitor it appropriately.</p> </div> <div class="paragraph"> <p>Typically we would define:</p> </div> <div class="ulist"> <ul> <li> <p>An HA replica is close to its upstream server, e.g. in the same Data Center - this minimises the latency for replication, and reduces RPO</p> </li> <li> <p>A DR replica is in a more remote location, so maybe risks being further behind in replication (thus higher RPO), but mitigates against catastrophic loss of a data center or similar. Note that "further behind" is still typically seconds for metadata, but can be minutes for submits with many GB of files.</p> </li> </ul> </div> <div class="sect3"> <h4 id="_further_resources">4.2.1. Further Resources</h4> <div class="ulist"> <ul> <li> <p><a href="https://community.perforce.com/s/article/3166">High Reliability Solutions</a></p> </li> </ul> </div> </div> <div class="sect3"> <h4 id="_creating_a_failover_replica_for_commit_or_edge_server">4.2.2. Creating a Failover Replica for Commit or Edge Server</h4> <div class="paragraph"> <p>A commit server is the ultimate store for submitted data, and also for any workspace state (WIP - work in progress) for users directly working with the commit server.</p> </div> <div class="paragraph"> <p>An edge server maintains its own copy of workspace state (WIP). If you have people connecting to an edge server, then any workspaces they create (and files they open for some action) will be only stored on the edge server. Thus it is normally recommended to have an HA backup server, so that users don’t lose their state in case of failover.</p> </div> <div class="paragraph"> <p>There is a concept of a "build edge" which is an edge server which only supports build farm users. In this scenario it may be deemed acceptable to not have an HA backup server, since in the case of failure of the edge, it can be re-seeded from the commit server. All build farm clients would be recreated from scratch so there would be no problems.</p> </div> </div> <div class="sect3"> <h4 id="_what_is_a_failover_replica">4.2.3. What is a Failover Replica?</h4> <div class="paragraph"> <p>As of 2018.2 release, p4d supports a <code>standby</code> replica (replica with <code>Services</code> set to <code>standby</code> or <code>forwarding-standby</code>). Such a replica performs a <code>journalcopy</code> replication of metadata, with a local pull thread to update its <code>db.*</code> files.</p> </div> <div class="paragraph"> <p>See also: <a href="https://community.perforce.com/s/article/16462">Configuring a Helix Core Standby</a> although the SDP script <a href="#_using_mkrep_sh">Section 4.3.4, “Using mkrep.sh”</a> does all you require.</p> </div> </div> <div class="sect3"> <h4 id="_mandatory_vs_non_mandatory_standbys">4.2.4. Mandatory vs Non-mandatory Standbys</h4> <div class="paragraph"> <p>When defining a standby server, you run <code>p4 server commit-standby</code> for example, to get:</p> </div> <div class="literalblock"> <div class="content"> <pre>ServerID: commit-standby Type: server Address: {standbyserver host}:{port number} Services: standby Options: nomandatory ReplicatingFrom: {commit-server-ID} Description: Standby server for {commit-server-ID}.</pre> </div> </div> <div class="paragraph"> <p>The <code>Options</code> field can be <code>nomandatory</code> or <code>mandatory</code>.</p> </div> <div class="paragraph"> <p>In the case of <code>mandatory</code>, the upstream commit server will wait until this server confirms it has processed and journal entries before responding to other downstream replicas. This allows easy failover, since it is guaranteed that no downstream servers is <strong>ahead</strong> of the replica.</p> </div> <div class="paragraph"> <p>Thus downstream servers can simply be re-directed to point to the standby and will carry on working without problems.</p> </div> <div class="admonitionblock important"> <table> <tr> <td class="icon"> <i class="fa icon-important" title="Important"></i> </td> <td class="content"> If a server which is marked as <code>mandatory</code> goes offline for any reason, the replication to other replicas will STOP - and it may not be obvious why it has stopped! Thus it is very important to monitor very carefully your "mandatory" replicas! </td> </tr> </table> </div> <div class="paragraph"> <p>If set to <code>nomandatory</code> then there is no risk of delaying dowsntream replicas, however there is equally no guarantee that they will be able to switch seamlessly over to the new server.</p> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> We recommend creating <code>mandatory</code> replica(s) if the server is local to its commit server, and also if you have good monitoring in place to quickly detect replication lag or other issues. </td> </tr> </table> </div> </div> <div class="sect3"> <h4 id="_server_host_naming_conventions">4.2.5. Server host naming conventions</h4> <div class="paragraph"> <p>This is recommended, but not a requirement for SDP scripts to implement failover.</p> </div> <div class="ulist"> <ul> <li> <p>Use a name that does not indicate switchable roles, e.g. don’t indicate in the name whether a host is a master/primary or backup, or edge server and it’s backup. This might otherwise lead to confusion once you have performed a failover and the host name is no longer appropriate.</p> </li> <li> <p>Use names ending numeric designators, e.g. -01 or -05. The goal is to avoid being in a post-failover situation where a machine with <code>master</code> or <code>primary</code> is actually the backup. Also, the assumption is that host names will never need to change.</p> </li> <li> <p>While you don’t want switchable roles baked into the hostname, you can have static roles, e.g. use p4d vs. p4p in the host name (as those generally don’t change). The p4d could be primary, standby, edge, edge’s standby (switchable roles).</p> </li> <li> <p>Using a short geographic site is sometimes helpful/desirable. If used, use the same site tag used in the ServerID, e.g. aus. Valid site tags should be listed in: <code>/p4/common/config/SiteTags.cfg</code> - see <a href="#_using_mkrep_sh">Section 4.3.4, “Using mkrep.sh”</a></p> </li> <li> <p>Using a short tag to indicate the major OS version is sometimes helpful/desirable, eg. c7 for CentOS 7, or r8 for RHEL 8. This is based on the idea that when the major OS is upgraded, you either move to new hardware, or change the host name (an exception to the rule above about never changing the hostname). This option maybe overkill for many sites.</p> </li> <li> <p>End users should reference a DNS name that may include the site tag, but would exclude the number, OS indicator, and server type (<code>p4d</code>/<code>p4p</code>/<code>p4broker</code>), replacing all that with just <code>perforce</code> or optionally just <code>p4</code>. General idea is that users needn’t be bothered by under-the-covers tech of whether something is a proxy or replica.</p> </li> <li> <p>For edge servers, it is advisable to include <code>edge</code> in both the host and DNS name, as users and admins needs to be aware of the functional differences due to a server being an edge server.</p> </li> </ul> </div> <div class="paragraph"> <p>Examples:</p> </div> <div class="ulist"> <ul> <li> <p><code>p4d-aus-r7-03</code>, a master in Austin on RHEL 7, pointed to by a DNS name like <code>p4-aus</code>.</p> </li> <li> <p><code>p4d-aus-03</code>, a master in Austin (no indication of server OS), pointed to by a DNS name like <code>p4-aus</code>.</p> </li> <li> <p><code>p4d-aus-r7-04</code>, a standby replica in Austin on RHEL 7, not pointed to by a DNS until failover, at which point it gets pointed to by <code>p4-aus</code>.</p> </li> <li> <p><code>p4p-syd-r8-05</code>, a proxy in Sydney on RHEL 8, pointed to by a DNS name like <code>p4-syd</code>.</p> </li> <li> <p><code>p4d-syd-r8-04</code>, a replica that replaced the proxy in Sydney, on RHEL 8, pointed to by a DNS name like <code>p4-syd</code> (same as the proxy it replaced).</p> </li> <li> <p><code>p4d-edge-tok-s12-03</code>, an edge in Tokyo running SuSE12, pointed to by a DNS name like <code>p4edge-tok</code>.</p> </li> <li> <p><code>p4d-edge-tok-s12-04</code>, a replica of an edge in Tokyo running SuSE12, not pointed to by a DNS name until failover, at which point it gets pointed to by <code>p4edge-tok</code>.</p> </li> </ul> </div> <div class="paragraph"> <p>FQDNs (fully qualified DNS names) of short DNS names used in these examples would also exist, and would be based on the same short names.</p> </div> </div> </div> <div class="sect2"> <h3 id="_full_one_way_replication">4.3. Full One-Way Replication</h3> <div class="paragraph"> <p>Perforce supports a full one-way <a href="https://www.perforce.com/perforce/doc.current/manuals/p4sag/Content/P4SAG/replication.html">replication</a> of data from a master server to a replica, including versioned files. The <a href="https://www.perforce.com/manuals/cmdref/Content/CmdRef/p4_pull.html#p4_pull">p4 pull</a> command is the replication mechanism, and a replica server can be configured to know it is a replica and use the replication command. The p4 pull mechanism requires very little configuration and no additional scripting. As this replication mechanism is simple and effective, we recommend it as the preferred replication technique. Replica servers can also be configured to only contain metadata, which can be useful for reporting or offline checkpointing purposes. See the Distributing Perforce Guide for details on setting up replica servers.</p> </div> <div class="paragraph"> <p>If you wish to use the replica as a read-only server, you can use the <a href="https://www.perforce.com/perforce/doc.current/manuals/p4sag/Content/P4SAG/chapter.broker.html">P4Broker</a> to direct read-only commands to the replica or you can use a forwarding replica. The broker can do load balancing to a pool of replicas if you need more than one replica to handle your load.</p> </div> <div class="sect3"> <h4 id="_replication_setup">4.3.1. Replication Setup</h4> <div class="paragraph"> <p>To configure a replica server, first configure a machine identically to the master server (at least as regards the link structure such as <code>/p4</code>, <code>/p4/common/bin</code> and <code>/p4/<strong><em>instance</em></strong>/*</code>), then install the SDP on it to match the master server installation. Once the machine and SDP install is in place, you need to configure the master server for replication.</p> </div> <div class="paragraph"> <p>Perforce supports many types of replicas suited to a variety of purposes, such as:</p> </div> <div class="ulist"> <ul> <li> <p>Real-time backup,</p> </li> <li> <p>Providing a disaster recovery solution,</p> </li> <li> <p>Load distribution to enhance performance,</p> </li> <li> <p>Distributed development,</p> </li> <li> <p>Dedicated resources for automated systems, such as build servers, and more.</p> </li> </ul> </div> <div class="paragraph"> <p>We always recommend first setting up the replica as a read-only replica and ensuring that everything is working. Once that is the case you can easily modify server specs and configurables to change it to a forwarding replica, or an edge server etc.</p> </div> </div> <div class="sect3"> <h4 id="_replication_setup_for_failover">4.3.2. Replication Setup for Failover</h4> <div class="paragraph"> <p>This is just a special case of replication, but implementing <a href="#_what_is_a_failover_replica">Section 4.2.3, “What is a Failover Replica?”</a></p> </div> <div class="paragraph"> <p>Please note the section below <a href="#_using_mkrep_sh">Section 4.3.4, “Using mkrep.sh”</a> which implements many details.</p> </div> </div> <div class="sect3"> <h4 id="_pre_requisites_for_failover">4.3.3. Pre-requisites for Failover</h4> <div class="paragraph"> <p>These are vital as part of your planning.</p> </div> <div class="ulist"> <ul> <li> <p>Obtain and install a license for your replica(s)</p> <div class="paragraph"> <p>Your commit or standard server has a license file (tied to IP address), while your replicas do not require one to function as replicas.</p> </div> <div class="paragraph"> <p>However, in order for a replica to function as a replacement for a commit or standard server, it must have a suitable license installed.</p> </div> <div class="paragraph"> <p>This should be requested when the replica is first created. See the form: <a href="https://www.perforce.com/support/duplicate-server-request" class="bare">https://www.perforce.com/support/duplicate-server-request</a></p> </div> </li> <li> <p>Review your authentication mechanism (LDAP etc) - is the LDAP server contactable from the replica machine (firewalls etc configured appropriately)</p> </li> <li> <p>Review all your triggers and how they are deployed - will they work on the failover host?</p> <div class="paragraph"> <p>Is the right version of Perl/Python etc correctly installed and configured on the failover host with all imported libraries?</p> </div> </li> </ul> </div> <div class="admonitionblock important"> <table> <tr> <td class="icon"> <i class="fa icon-important" title="Important"></i> </td> <td class="content"> TEST, TEST, TEST!!! It is important to test the above issues as part of your planning. For peace of mind you don’t want to be finding problems at the time of trying to failover for real, which may be in the middle of the night! </td> </tr> </table> </div> </div> <div class="sect3"> <h4 id="_using_mkrep_sh">4.3.4. Using mkrep.sh</h4> <div class="paragraph"> <p>This script automates the following:</p> </div> <div class="ulist"> <ul> <li> <p>creation of all the configurables for a replica appropriate to its type (e.g. forwarding-replica, forwarding-standby, edge-server etc).</p> </li> <li> <p>standard naming conventions are used for server ids, service user names etc. This simplifies managing multiple server/replica topologies and understanding the intended use of a replica (e.g. that it is intended for HA - high availability)</p> </li> <li> <p>creation of service user account, password, and with appropriate permissions</p> </li> <li> <p>creation of server spec</p> </li> <li> <p>detailed instructions to follow in order to create a checkpoint and restore on the replica server</p> </li> </ul> </div> <div class="paragraph"> <p>Prerequisites:</p> </div> <div class="ulist"> <ul> <li> <p>You must have a server spec for your master server, typically defined with Services: <code>commit-server</code> (<code>standard</code> is fine if no edge servers are to be created, but it is not a problem to use <code>commit-server</code> even without any edge servers) - use the serverid (output of <code>p4 serverid</code>) as the name.</p> </li> <li> <p>You should be running p4d 2018.2 or later (earlier versions of SDP address the use of pre 2018.2 servers) and 2020.1+ is recommended</p> </li> <li> <p>You should have a configuration file which defines site tags - this is part of naming and is validated.</p> </li> </ul> </div> <div class="sect4"> <h5 id="_server_types">4.3.4.1. Server Types</h5> <div class="paragraph"> <p>These are:</p> </div> <div class="ulist"> <ul> <li> <p>ha - High Availability</p> </li> <li> <p>ham - High Availability (Metadata only)</p> </li> <li> <p>ro - Read only replica</p> </li> <li> <p>rom - Read only replica (Metadata only)</p> </li> <li> <p>fr - Forwarding replica</p> </li> <li> <p>fs - Forwarding standby</p> </li> <li> <p>frm - (Metadata only)</p> </li> <li> <p>fsm - (Metadata only)</p> </li> <li> <p>ffr - Filtered forwarding replica</p> </li> <li> <p>edge - Edge server</p> </li> </ul> </div> <div class="paragraph"> <p>Replicas with <code>standby</code> in the name are always unfiltered, and use the <code>journalcopy</code> method of replication, which copies a byte-for-byte verbatim journal file rather than one that is merely logically equivalent. This can also perform better as it multi-threads the actions of the replica to pull the journal and use it to update local metadata.</p> </div> </div> <div class="sect4"> <h5 id="_example">4.3.4.2. Example</h5> <div class="paragraph"> <p>An example run is:</p> </div> <div class="literalblock"> <div class="content"> <pre>/p4/common/bin/mkrep.sh -i 1 -t fs -s bos -r p4d-bos-02 -skip_ssh</pre> </div> </div> <div class="paragraph"> <p>The above will:</p> </div> <div class="ulist"> <ul> <li> <p>Create a replica for instance <code>1</code></p> </li> <li> <p>Of type <code>fs</code> (forwarding standby) - with appropriate configurables</p> </li> <li> <p>For site <code>bos</code> (e.g. Boston)</p> </li> <li> <p>On host name <code>p4d-bos-02</code></p> </li> <li> <p>Without checking that passwordless ssh is possible to the host <code>p4d-bos-02</code></p> </li> </ul> </div> <div class="paragraph"> <p>The tag has several purposes:</p> </div> <div class="ulist"> <ul> <li> <p>Short Hand. Each tag represents a combination of 'Type:' and fully qualified 'Services:' values used in server specs.</p> </li> <li> <p>Distillation. Only the most useful Type/Services combinations have a shorthand form.</p> </li> <li> <p>For forwarding replicas, the name includes the critical distinction of whether any replication filtering is used; as filtering of any kind disqualifies a replica from being a potential failover target. (No such distinction is needed for edge servers, which are filtered by definition).</p> </li> </ul> </div> </div> <div class="sect4"> <h5 id="_mkrep_sh_output">4.3.4.3. Mkrep.sh output</h5> <div class="paragraph"> <p>The output (which is also written to a log file in <code>/p4/<instance>/logs/mkrep.*</code>) describes a number of steps required to continue setting up the replica, e.g.</p> </div> <div class="ulist"> <ul> <li> <p>Rotate the current live journal (to save the configuration parameters required)</p> </li> <li> <p>Copy across latest checkpoint and the subsequent rotated journals to the replica host machine</p> </li> <li> <p>Restore the copied checkpoints/journals into <code>/p4/<instance>/root</code> (and <code>offline_db</code>)</p> </li> <li> <p>Create a password file for service user</p> </li> <li> <p>Create appropriate server.id files</p> </li> <li> <p>Login the service user to the upstream server (usually commit server)</p> </li> <li> <p>Start the replica process</p> </li> <li> <p>Monitor that all is well with <code>p4 pull -lj</code></p> </li> </ul> </div> <div class="paragraph"> <p>More details on these steps can be found in the manual process below as well as the actualy mkrep.sh output.</p> </div> <div class="listingblock"> <div class="title">Usage</div> <div class="content"> <pre class="highlight"><code> echo "USAGE for $THISSCRIPT v$Version: $THISSCRIPT -i <SDP_Instance> -t <Type> -s <Site_Tag> -r <Replica_Host> [-f <From_ServerID>] [-p] [-ssh_opts=\"opts\"] [-skip_ssh] [-L <log>] [-si] [-v<n>] [-n] [-D] or $THISSCRIPT [-h|-man|-V] " if [[ $style == -man ]]; then echo -e " DESCRIPTION: This script creates makes a replica, and provides enough information to make it ready in all respects. OPTIONS: -i <SDP_Instance> Specify the SDP Instance. -t <Type> Specify the replica type tag. The type corresponds to the 'Type:' and 'Services:' field of the server spec, which describes the type of services offered by a given replica. Valid values are: * ha: High Availability mandatory standby replica, for 'p4 failover' (P4D 2018.2+) * ham: High Availability metadata-only mandatory standby replica, for 'p4 failover' (P4D 2018.2+) * ro: Read-Only standby replica. * rom: Read-Only standby replica, Metadata only. * fr: Forwarding Replica (Unfiltered). * fs: Forwarding Standby (Unfiltered). * frm: Forwarding Replica (Unfiltered, Metadata only). * fsm: Forwarding Standby (Unfiltered, Metadata only). * ffr: Filtered Forwarding Replica. Not a valid failover target. * edge: Edge Server. Filtered by definition. Replicas with 'standby' are always unfiltered, and use the 'journalcopy' method of replication, which copies a byte-for-byte verbatim journal file rather than one that is merely logically equivalent. The tag has several purposes: 1. Short Hand. Each tag represents a combination of 'Type:' and fully qualified 'Services:' values used in server specs. 2. Distillation. Only the most useful Type/Services combinations have a shorthand form. 3. For forwarding replicas, the name includes the critical distinction of whether any replication filtering is used; as filtering of any kind disqualifies a replica from being a potential failover target. (No such distinction is needed for edge servers, which are filtered by definition). -s <Site_Tag> Specify a geographic site tag indicating the location and/or data center where the replica will physically be located. Valid site tags are defined in the site tags file: $SiteTagsFile Current valid site tags defined in this file are: $(grep -v '^#' "$SiteTagsFile" 2>&1|grep -v '$^'|sed 's:^:\t:g') -r <Replica_Host> Specify the target replica host. -f <From_ServerID> Specify ServerID of the P4TARGET server from which we are replicating. This is used to populate the 'ReplicatingFrom' field of the server spec. The value must be a valid ServerID. By default, this is determined dynamically checking the ServerID of the master server. This option should be used if the target is something other than the master. For example, to create an HA replica of an edge server, you might specify something like '-f p4d_edge_syd'. -p This script performs a check to ensure that the Protections table grants super access to the group $ServiceUsersGroup. By default, an error is displayed if the check fails, i.e. if super user access for the group $ServiceUsersGroup cannot be verified. This is because, by default, we want to avoid making changes to the Protections table. Some sites have local policies or custom automation that requires site-specific procedures to update the Protections table. If '-p' is specified, an attempt is made to append the Protections table an entry like: super group $ServiceUsersGroup * //... -ssh_opts=\"opts\" Specify '-ssh_opts' to pass paraemters on to the ssh command. For example, to specify ssh operation on non-standard port 2222, specify '-ssh_opts=\"-p 2222\"'. -skip_ssh Specify '-skip_ssh' to skip the SSH access preflight check. This is useful if you only intend to do the metadata preparation phase of creating a new replica, prior to SSH being setup or perhaps even prior to the hardware being available. -v<n> Set verbosity 1-5 (-v1 = quiet, -v5 = highest). -L <log> Specify the path to a log file, or the special value 'off' to disable logging. By default, all output (stdout and stderr) goes in the logs directory referenced by \$LOGS. NOTE: This script is self-logging. That is, output displayed on the screen is simultaneously captured in the log file. Do not run this script with redirection operators like '> log' or '2>&1', and do not use 'tee.' -si Operate silently. All output (stdout and stderr) is redirected to the log only; no output appears on the terminal. This cannot be used with '-L off'. -n No-Op. Prints commands instead of running them. -D Set extreme debugging verbosity. -f Full Mode Setup: The completes an edge servers setup so no additional steps are required. This setup requires an ssh connection from the master to the edge to be in place first. It also requires the depot log journal and /p4 mounts to be in place and setup as expected. This setup assumes a standard SDP setup. HELP OPTIONS: -h Display short help message -man Display man-style help message -V Dispay version info for this script and its libraries. DEPENDENCIES: This script depends on ssh keys being defined to allow the Perforce operating system user ($OSUSER) to ssh to any necessary machines without a password. This script assumes the replica host already has the SDP fully configured. FILES: This Site Tags file defines the list of valid geographic site tags: $SiteTagsFile EXAMPLES: Prepare an edge server to run on host syc-helix-04: $THISSCRIPT -i acme -t edge -s syd -r syc-helix-04 "</code></pre> </div> </div> </div> </div> <div class="sect3"> <h4 id="_setting_up_a_replica_manually">4.3.5. Setting up a Replica Manually</h4> <div class="paragraph"> <p>We strongly recommend the use of <code>mkrep.sh</code> as it avoids forgetting particular details. However it is possible to manually configure a replica.</p> </div> <div class="paragraph"> <p>In the sample below, the replica name will be <code>p4d_fr_bos</code>, it is instance 1 on a particular host, the service user name is <code>svc_p4d_fr_bos</code>, and the master server’s hostname is <code>svrmaster</code>. This is following <a href="#_server_host_naming_conventions">Section 4.2.5, “Server host naming conventions”</a></p> </div> <div class="paragraph"> <p>The following sample commands illustrate how to setup a simple read-only replica.</p> </div> <div class="paragraph"> <p>First we ensure that <code>journalPrefix</code> is set appropriately for the master server (in this case we assume instance <code>1</code> rather than a named instance):</p> </div> <div class="literalblock"> <div class="content"> <pre>p4 configure set master#journalPrefix=/p4/1/checkpoints/p4_1</pre> </div> </div> <div class="paragraph"> <p>Then we set values for the replica itself:</p> </div> <div class="literalblock"> <div class="content"> <pre>p4 configure set p4d_fr_bos#P4TARGET=svrmaster:1667 p4 configure set "p4d_fr_bos#startup.1=pull -i 1" p4 configure set "p4d_fr_bos#startup.2=pull -u -i 1" p4 configure set "p4d_fr_bos#startup.3=pull -u -i 1" p4 configure set "p4d_fr_bos#startup.4=pull -u -i 1" p4 configure set "p4d_fr_bos#startup.5=pull -u -i 1" p4 configure set "p4d_fr_bos#db.replication=readonly" p4 configure set "p4d_fr_bos#lbr.replication=readonly" p4 configure set p4d_fr_bos#serviceUser=svc_p4d_fr_bos</pre> </div> </div> <div class="paragraph"> <p>Then the following also need to be setup:</p> </div> <div class="ulist"> <ul> <li> <p>Create a service user for the replica (Add the <code>Type: service</code> field to the user form before saving):</p> <div class="literalblock"> <div class="content"> <pre>p4 user -f svc_p4d_fr_bos</pre> </div> </div> </li> <li> <p>Set the service user’s password:</p> <div class="literalblock"> <div class="content"> <pre>p4 passwd svc_p4d_fr_bos</pre> </div> </div> </li> <li> <p>Add the service user svc_p4d_fr_bos to a specific group, e.g. <code>ServiceUsers</code> which has a <code>Timeout</code> field set to <code>unlimited</code>:</p> <div class="literalblock"> <div class="content"> <pre>p4 group ServiceUsers</pre> </div> </div> </li> <li> <p>Make sure the <code>ServiceUsers</code> group has super access in protections table:</p> <div class="literalblock"> <div class="content"> <pre>p4 protect</pre> </div> </div> </li> </ul> </div> <div class="paragraph"> <p>Now that the settings are in the master server, you need to create a checkpoint to seed the replica. Run:</p> </div> <div class="literalblock"> <div class="content"> <pre>/p4/common/bin/daily_checkpoint.sh 1</pre> </div> </div> <div class="paragraph"> <p>When the checkpoint finishes, rsync the checkpoint plus the versioned files over to the replica:</p> </div> <div class="literalblock"> <div class="content"> <pre>rsync -avz /p4/1/checkpoints/p4_1.ckp.###.gz perforce@p4d-bos-02:/p4/1/checkpoints/.</pre> </div> </div> <div class="literalblock"> <div class="content"> <pre>rsync -avz /p4/1/depots/ perforce@p4d-bos-02:/p4/1/depots/</pre> </div> </div> <div class="paragraph"> <p>(Assuming perforce is the OS user name and <code>p4d-bos-02</code> is the name of the replica server in the commands above, and that <mark>#</mark> is the checkpoint number created by the daily backup.)</p> </div> <div class="paragraph"> <p>Once the rsync finishes, go to the replica machine run the following:</p> </div> <div class="literalblock"> <div class="content"> <pre>/p4/1/bin/p4d_1 -r /p4/1/root -jr -z /p4/1/checkpoints/p4_1.ckp.###.gz</pre> </div> </div> <div class="paragraph"> <p>Login as the service user (specifying appropriate password when prompted), and making sure that the login ticket generated is stored in the same place as specified in the P4TICKETS configurable value set above for the replica (the following uses bash syntax):</p> </div> <div class="literalblock"> <div class="content"> <pre>source /p4/common/bin/p4_vars 1 /p4/1/bin/p4_1 -p svrmaster:1667 -u svc_p4d_fr_bos login</pre> </div> </div> <div class="paragraph"> <p>Start the replica instance (either using _init script or <code>systemctl</code> if on systemd):</p> </div> <div class="literalblock"> <div class="content"> <pre>/p4/1/bin/p4d_1_init start</pre> </div> </div> <div class="paragraph"> <p>Now, you can log into the replica server itself and run <code>p4 pull -lj</code> to check to see if replication is working. If you see any numbers with a negative sign in front of them, replication is not working. The most likely cause of this is that the service user is not logged in. Rerun the steps above to login the service user and check again. If replication still is not working, check <code>/p4/1/logs/log</code> on the replica, and also look for authentication failures in the log for the master instance on svrmaster.</p> </div> <div class="paragraph"> <p>The final steps for setting up the replica server are to set up the crontab for the replica server.</p> </div> <div class="paragraph"> <p>To configure the ssh trust:</p> </div> <div class="paragraph"> <p>On both the master and replica servers, go to the perforce user’s home directory and run:</p> </div> <div class="literalblock"> <div class="content"> <pre>ssh-keygen -t rsa</pre> </div> </div> <div class="paragraph"> <p>Just use the defaults for the questions it asks.</p> </div> <div class="paragraph"> <p>Now from the master, run:</p> </div> <div class="literalblock"> <div class="content"> <pre>rsync -avz ~/.ssh/id_rsa.pub perforce@p4d-bos-02:~/.ssh/authorized_keys</pre> </div> </div> <div class="paragraph"> <p>and from the replica, run:</p> </div> <div class="literalblock"> <div class="content"> <pre>rsync -avz ~/.ssh/id_rsa.pub perforce@svrmaster:~/.ssh/authorized_keys</pre> </div> </div> <div class="paragraph"> <p>The crontab (/p4/p4.crontab) contains several lines which are prefixed by <code>/p4/common/bin/run_if_replica.sh</code> or <code>run_if_edge.sh</code> or <code>run_if_master.sh</code></p> </div> <div class="paragraph"> <p>These can be tested to make sure all is valid with:</p> </div> <div class="literalblock"> <div class="content"> <pre>/p4/common/bin/run_if_replica.sh 1 echo yes</pre> </div> </div> <div class="paragraph"> <p>If "yes" is output then SDP thinks the current hostname with instance 1 is a replica server. Similarly for edge/master.</p> </div> <div class="paragraph"> <p>The log files will be in <code>/p4/1/logs</code>, so you can check for any errors from each script.</p> </div> </div> </div> <div class="sect2"> <h3 id="_recovery_procedures">4.4. Recovery Procedures</h3> <div class="paragraph"> <p>There are three scenarios that require you to recover server data:</p> </div> <table class="tableblock frame-all grid-all stretch"> <colgroup> <col style="width: 33.3333%;"> <col style="width: 33.3333%;"> <col style="width: 33.3334%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-top">Metadata</th> <th class="tableblock halign-left valign-top">Depotdata</th> <th class="tableblock halign-left valign-top">Action required</th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">lost or corrupt</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Intact</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Recover metadata as described below</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Intact</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">lost or corrupt</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Call Perforce Support</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">lost or corrupt</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">lost or corrupt</p></td> <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"> <p>Recover metadata as described below.</p> </div> <div class="paragraph"> <p>Recover the hxdepots volume using your normal backup utilities.</p> </div></div></td> </tr> </tbody> </table> <div class="paragraph"> <p>Restoring the metadata from a backup also optimizes the database files.</p> </div> <div class="sect3"> <h4 id="_recovering_a_master_server_from_a_checkpoint_and_journals">4.4.1. Recovering a master server from a checkpoint and journal(s)</h4> <div class="paragraph"> <p>The checkpoint files are stored in the <code>/p4/<strong><em>instance</em></strong>/checkpoints</code> directory, and the most recent checkpoint is named <code>p4_<strong><em>instance</em></strong>.ckp.<strong><em>number</em></strong>.gz</code>. Recreating up-to-date database files requires the most recent checkpoint, from <code>/p4/<strong><em>instance</em></strong>/checkpoints</code> and the journal file from <code>/p4/<strong><em>instance</em></strong>/logs</code>.</p> </div> <div class="paragraph"> <p>To recover the server database manually, perform the following steps from the root directory of the server (/p4/instance/root).</p> </div> <div class="paragraph"> <p>Assuming instance 1:</p> </div> <div class="olist arabic"> <ol class="arabic"> <li> <p>Stop the Perforce Server by issuing the following command:</p> <div class="literalblock"> <div class="content"> <pre>/p4/1/bin/p4_1 admin stop</pre> </div> </div> </li> <li> <p>Delete the old database files in the <code>/p4/1/root/save</code> directory</p> </li> <li> <p>Move the live database files (db.*) to the save directory.</p> </li> <li> <p>Use the following command to restore from the most recent checkpoint.</p> <div class="literalblock"> <div class="content"> <pre>/p4/1/bin/p4d_1 -r /p4/1/root -jr -z /p4/1/checkpoints/p4_1.ckp.####.gz</pre> </div> </div> </li> <li> <p>To replay the transactions that occurred after the checkpoint was created, issue the following command:</p> <div class="literalblock"> <div class="content"> <pre>/p4/1/bin/p4d_1 -r /p4/1/root -jr /p4/1/logs/journal</pre> </div> </div> </li> </ol> </div> <div class="olist arabic"> <ol class="arabic" start="6"> <li> <p>Restart your Perforce server.</p> </li> </ol> </div> <div class="paragraph"> <p>If the Perforce service starts without errors, delete the old database files from <code>/p4/instance/root/save</code>.</p> </div> <div class="paragraph"> <p>If problems are reported when you attempt to recover from the most recent checkpoint, try recovering from the preceding checkpoint and journal. If you are successful, replay the subsequent journal. If the journals are corrupted, contact <a href="mailto:support@perforce.com">Perforce Technical Support</a>. For full details about backup and recovery, refer to the <a href="https://www.perforce.com/perforce/doc.current/manuals/p4sag/Content/P4SAG/chapter.backup.html">Perforce System Administrator’s Guide</a>.</p> </div> </div> <div class="sect3"> <h4 id="_recovering_a_replica_from_a_checkpoint">4.4.2. Recovering a replica from a checkpoint</h4> <div class="paragraph"> <p>This is very similar to creating a replica in the first place as described above.</p> </div> <div class="paragraph"> <p>If you have been running the replica crontab commands as suggested, then you will have the latest checkpoints from the master already copied across to the replica through the use of <a href="#_sync_replica_sh">Section 7.4.27, “sync_replica.sh”</a>.</p> </div> <div class="paragraph"> <p>See the steps in the script <a href="#_sync_replica_sh">Section 7.4.27, “sync_replica.sh”</a> for details (note that it deletes the state and rdb.lbr files from the replica root directory so that the replica starts replicating from the start of a journal).</p> </div> <div class="paragraph"> <p>Remember to ensure you have logged the service user in to the master server (and that the ticket is stored in the correct location as described when setting up the replica).</p> </div> </div> <div class="sect3"> <h4 id="_recovering_from_a_tape_backup">4.4.3. Recovering from a tape backup</h4> <div class="paragraph"> <p>This section describes how to recover from a tape or other offline backup to a new server machine if the server machine fails. The tape backup for the server is made from the hxdepots volume. The new server machine must have the same volume layout and user/group settings as the original server. In other words, the new server must be as identical as possible to the server that failed.</p> </div> <div class="paragraph"> <p>To recover from a tape backup, perform the following steps (assuming instance <code>1</code>):</p> </div> <div class="olist arabic"> <ol class="arabic"> <li> <p>Recover the hxdepots volume from your backup tape.</p> </li> <li> <p>Create the <code>/p4</code> convenience directory on the OS volume.</p> </li> <li> <p>Create the directories <code>/metadata/p4/1/root/save</code> and <code>/metadata/p4/1/offline_db</code>.</p> </li> <li> <p>Change ownership of these directories to the OS account that runs the Perforce processes.</p> </li> <li> <p>Switch to the Perforce OS account, and create a link in the <code>/p4</code> directory to <code>/depotadata/p4/1</code>.</p> </li> <li> <p>Create a link in the <code>/p4</code> directory to <code>/hxdepots/p4/common</code>.</p> </li> <li> <p>As a super-user, reinstall and enable the <code>init.d</code> scripts</p> </li> <li> <p>Find the last available checkpoint, under <code>/p4/1/checkpoints</code></p> </li> <li> <p>Recover the latest checkpoint by running:</p> <div class="literalblock"> <div class="content"> <pre>/p4/1/bin/p4d_1 -r /p4/1/root -jr -z <last_ckp_file></pre> </div> </div> </li> <li> <p>Recover the checkpoint to the offline_db directory (assuming instance 1):</p> <div class="literalblock"> <div class="content"> <pre>/p4/1/bin/p4d_1 -r /p4/1/offline_db -jr -z <last_ckp_file></pre> </div> </div> </li> <li> <p>Reinstall the Perforce server license to the server root directory.</p> </li> <li> <p>Start the perforce service by running 1/p4/1/bin/p4d_1_init start`</p> </li> <li> <p>Verify that the server instance is running.</p> </li> <li> <p>Reinstall the server crontab or scheduled tasks.</p> </li> <li> <p>Perform any other initial server machine configuration.</p> </li> <li> <p>Verify the database and versioned files by running the <code>p4verify.sh</code> script. Note that files using the <a href="https://www.perforce.com/manuals/cmdref/Content/CmdRef/file.types.synopsis.modifiers.html">+k</a> file type modifier might be reported as BAD! after being moved. Contact Perforce Technical Support for assistance in determining if these files are actually corrupt.</p> </li> </ol> </div> </div> <div class="sect3"> <h4 id="_failover_to_a_replicated_standby_machine">4.4.4. Failover to a replicated standby machine</h4> <div class="paragraph"> <p>See <a href="SDP_Failover_Guide.pdf">SDP Failover Guide (PDF)</a> or <a href="SDP_Failover_Guide.html">SDP Failover Guide (HTML)</a> for detailed steps.</p> </div> </div> </div> </div> </div> <div class="sect1"> <h2 id="_server_upgrades">5. Server Upgrades</h2> <div class="sectionbody"> <div class="paragraph"> <p>This section describes typical maintenance tasks and best practices for administering server machines.</p> </div> <div class="sect2"> <h3 id="_upgrading_an_existing_sdp_installation">5.1. Upgrading an existing SDP installation</h3> <div class="paragraph"> <p>If you have an earlier version of the Server Deployment Package (SDP) installed, you’ll want to be aware of the new -test flag to the SDP setup script, <code>mkdirs.sh</code> e.g.</p> </div> <div class="literalblock"> <div class="content"> <pre>sudo mkdirs.sh 1 -test</pre> </div> </div> <div class="paragraph"> <p>This will install into <code>/tmp</code> and allow you to recursively diff the installed files with your existing installation and manually update as necessary.</p> </div> <div class="paragraph"> <p>See the instructions in the file README.md / README.html in the root of the SDP directory.</p> </div> </div> <div class="sect2"> <h3 id="_p4d_server_upgrades">5.2. P4D Server upgrades</h3> <div class="paragraph"> <p>Upgrading a Helix Core server instance in the SDP framework is a simple process involving a few steps.</p> </div> <div class="ulist"> <ul> <li> <p>Download the new p4 and p4d executables for your OS from <a href="ftp://ftp.perforce.com">ftp.perforce.com</a> and place them in <code>/p4/common/bin</code></p> </li> <li> <p>Run:</p> <div class="literalblock"> <div class="content"> <pre>/p4/common/bin/upgrade.sh <instance></pre> </div> </div> <div class="paragraph"> <p>e.g.</p> </div> <div class="literalblock"> <div class="content"> <pre>/p4/common/bin/upgrade.sh 1</pre> </div> </div> </li> <li> <p>If you are running replicas, upgrade the replicas first, and then the master (outside → in)</p> </li> </ul> </div> <div class="paragraph"> <p>Please refer to details for <a href="#_upgrade_sh">Section 7.3.1, “upgrade.sh”</a></p> </div> </div> <div class="sect2"> <h3 id="_database_modifications">5.3. Database Modifications</h3> <div class="paragraph"> <p>Occasionally modifications are made to the Perforce database from one release to another. For example, server upgrades and some recovery procedures modify the database.</p> </div> <div class="paragraph"> <p>When upgrading the server, replaying a journal patch, or performing any activity that modifies the db.* files, you must restart the offline checkpoint process so that the files in the offline_db directory match the ones in the live server directory. The easiest way to restart the offline checkpoint process is to run the live_checkpoint script after modifying the db.* files, as follows:</p> </div> <div class="literalblock"> <div class="content"> <pre>/p4/common/bin/live_checkpoint.sh 1</pre> </div> </div> <div class="paragraph"> <p>This script makes a new checkpoint of the modified database files in the live <code>root</code> directory, then recovers that checkpoint to the <code>offline_db</code> directory so that both directories are in sync. This script can also be used anytime to create a checkpoint of the live database.</p> </div> <div class="paragraph"> <p>This command should be run when an error occurs during offline checkpointing. It restarts the offline checkpoint process from the live database files to bring the offline copy back in sync. If the live checkpoint script fails, contact Perforce Consulting at <a href="mailto:consulting@perforce.com">consulting@perforce.com</a>.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="_maximizing_server_performance">6. Maximizing Server Performance</h2> <div class="sectionbody"> <div class="paragraph"> <p>The following sections provide some guidelines for maximizing the performance of the Perforce Server, using tools provided by the SDP. More information on this topic can be found in the <a href="https://community.perforce.com/s/article/2529">Knowledge Base</a>.</p> </div> <div class="sect2"> <h3 id="_ensure_transparent_huge_pages_thp_is_turned_off">6.1. Ensure Transparent Huge Pages (THP) is turned off</h3> <div class="paragraph"> <p>This is reference <a href="https://community.perforce.com/s/article/3005">KB Article on Platform Notes</a></p> </div> <div class="paragraph"> <p>There is a script in the SDP which will do this:</p> </div> <div class="literalblock"> <div class="content"> <pre>/p4/sdp/Server/Unix/setup/os_tweaks.sh</pre> </div> </div> <div class="paragraph"> <p>It needs to be run as <code>root</code> or using <code>sudo</code>. This will not persist after system is rebooted.</p> </div> <div class="admonitionblock tip"> <table> <tr> <td class="icon"> <i class="fa icon-tip" title="Tip"></i> </td> <td class="content"> We recommend the usage of <code>tuned</code> </td> </tr> </table> </div> <div class="paragraph"> <p>Install as appropriate for your Linux distribution (so as <code>root</code>):</p> </div> <div class="literalblock"> <div class="content"> <pre>yum install tuned</pre> </div> </div> <div class="paragraph"> <p>or</p> </div> <div class="literalblock"> <div class="content"> <pre>apt-get install tuned</pre> </div> </div> <div class="olist arabic"> <ol class="arabic"> <li> <p>Create a customized <code>tuned</code> profile with disabled THP. Create a new directory in <code>/etc/tuned</code> directory with desired profile name:</p> <div class="literalblock"> <div class="content"> <pre>mkdir /etc/tuned/nothp_profile</pre> </div> </div> </li> <li> <p>Then create a new <code>tuned.conf</code> file for <code>nothp_profile</code>, and insert the new tuning info:</p> <div class="literalblock"> <div class="content"> <pre>cat <<EOF > /etc/tuned/nothp_profile/tuned.conf [main] include= throughput-performance</pre> </div> </div> <div class="literalblock"> <div class="content"> <pre>[vm] transparent_hugepages=never EOF</pre> </div> </div> </li> <li> <p>Make the script executable</p> <div class="literalblock"> <div class="content"> <pre>chmod +x /etc/tuned/nothp_profile/tuned.conf</pre> </div> </div> </li> <li> <p>Enable <code>nothp_profile</code> using the <code>tuned-adm</code> command.</p> <div class="literalblock"> <div class="content"> <pre>tuned-adm profile nothp_profile</pre> </div> </div> </li> <li> <p>This change will immediately take effect and persist after reboots. To verify if THP are disabled or not, run below command:</p> <div class="literalblock"> <div class="content"> <pre>cat /sys/kernel/mm/transparent_hugepage/enabled always madvise [never]</pre> </div> </div> </li> </ol> </div> </div> <div class="sect2"> <h3 id="_putting_server_locks_directory_into_ram">6.2. Putting server.locks directory into RAM</h3> <div class="paragraph"> <p>The <code>server.locks</code> directory is maintained in the $P4ROOT (so <code>/p4/1/root</code>) for a running server. This directory contains a tree of 17 byte long files which is used for lock co-ordination amongst p4d processes.</p> </div> <div class="paragraph"> <p>This directory can be removed every time the p4d instance is restarted, so it is safe to put it into a tmpfs filesystem.</p> </div> <div class="paragraph"> <p>Even on a large installation with many hundreds or thousands of users, this directory will be unlikely to exceed 1GB, so a 2GB filesystem will be ample.</p> </div> <div class="paragraph"> <p>Instructions (as user <code>root</code>):</p> </div> <div class="olist arabic"> <ol class="arabic"> <li> <p>Create directory to mount, and change ownership to <code>perforce</code> user (or <code>$OSUSER</code> if SDP config specifies a different name)</p> <div class="literalblock"> <div class="content"> <pre>mkdir /hxserverlocks chown perforce:perforce /hxserverlocks</pre> </div> </div> </li> <li> <p>Add a line to <code>/etc/fstab</code>:</p> <div class="literalblock"> <div class="content"> <pre>tmpfs /hxserverlocks tmpfs size=1GB,mode=0755 0 0</pre> </div> </div> </li> <li> <p>Mount the drive:</p> <div class="literalblock"> <div class="content"> <pre>mount -a</pre> </div> </div> </li> <li> <p>Check it is looking correct:</p> <div class="literalblock"> <div class="content"> <pre>df -h</pre> </div> </div> </li> </ol> </div> <div class="paragraph"> <p>As user <code>perforce</code>, set the configurable, specifying the serverid of your server (to ensure it is not set globally and picked up by all replicas):</p> </div> <div class="literalblock"> <div class="content"> <pre>p4 configure set <serverid>#server.locks.dir=<serverlocks dir></pre> </div> </div> <div class="literalblock"> <div class="content"> <pre>p4 configure set master.1#server.locks.dir=/p4serverlocks</pre> </div> </div> <div class="paragraph"> <p>This will take effect immediately - it does not require a server restart.</p> </div> </div> <div class="sect2"> <h3 id="_optimizing_the_database_files">6.3. Optimizing the database files</h3> <div class="paragraph"> <p>The Perforce Server’s database is composed of b-tree files. The server does not fully rebalance and compress them during normal operation. To optimize the files, you must checkpoint and restore the server. This normally only needs to be done very few months.</p> </div> <div class="paragraph"> <p>To minimize the size of back up files and maximize server performance, minimize the size of the db.have and db.label files.</p> </div> </div> <div class="sect2"> <h3 id="_p4v_performance_settings">6.4. P4V Performance Settings</h3> <div class="paragraph"> <p>These are covered in: <a href="https://community.perforce.com/s/article/2878" class="bare">https://community.perforce.com/s/article/2878</a></p> </div> </div> <div class="sect2"> <h3 id="_proactive_performance_maintenance">6.5. Proactive Performance Maintenance</h3> <div class="paragraph"> <p>This section describes some things that can be done to proactively to enhance scalability and maintain performance.</p> </div> <div class="sect3"> <h4 id="_limiting_large_requests">6.5.1. Limiting large requests</h4> <div class="paragraph"> <p>To prevent large requests from overwhelming the server, you can limit the amount of data and time allowed per query by setting the maxresults, maxscanrows and maxlocktime parameters to the lowest setting that does not interfere with normal daily activities. As a good starting point, set maxscanrows to maxresults * 3; set maxresults to slightly larger than the maximum number of files the users need to be able to sync to do their work; and set maxlocktime to 30000 milliseconds. These values must be adjusted up as the size of your server and the number of revisions of the files grow. To simplify administration, assign limits to groups rather than individual users.</p> </div> <div class="paragraph"> <p>To prevent users from inadvertently accessing large numbers of files, define their client view to be as narrow as possible, considering the requirements of their work. Similarly, limit users' access in the protections table to the smallest number of directories that are required for them to do their job.</p> </div> <div class="paragraph"> <p>Finally, keep triggers simple. Complex triggers increase load on the server.</p> </div> </div> <div class="sect3"> <h4 id="_offloading_remote_syncs">6.5.2. Offloading remote syncs</h4> <div class="paragraph"> <p>For remote users who need to sync large numbers of files, Perforce offers a <a href="https://www.perforce.com/perforce/doc.current/manuals/p4sag/Content/P4SAG/chapter.proxy.html">proxy server</a>. P4P, the Perforce Proxy, is run on a machine that is on the remote users' local network. The Perforce Proxy caches file revisions, serving them to the remote users and diverting that load from the main server.</p> </div> <div class="paragraph"> <p>P4P is included in the Windows installer. To launch P4P on Unix machines, copy the <code>/p4/common/etc/init.d/p4p_1_init script</code> to <code>/p4/1/bin/p4p_1_init</code>. Then review and customize the script to specify your server volume names and directories.</p> </div> <div class="paragraph"> <p>P4P does not require special hardware but it can be quite CPU intensive if it is working with binary files, which are CPU-intensive to attempt to compress. It doesn’t need to be backed up. If the P4P instance isn’t working, users can switch their port back to the main server and continue working until the instance of P4P is fixed.</p> </div> </div> </div> </div> </div> <div class="sect1"> <h2 id="_tools_and_scripts">7. Tools and Scripts</h2> <div class="sectionbody"> <div class="paragraph"> <p>This section describes the various scripts and files provided as part of the SDP package.</p> </div> <div class="sect2"> <h3 id="_general_sdp_usage">7.1. General SDP Usage</h3> <div class="paragraph"> <p>This section presents an overview of the SDP scripts and tools, with details covered in subsequent sections.</p> </div> <div class="sect3"> <h4 id="_linux">7.1.1. Linux</h4> <div class="paragraph"> <p>Most scripts and tools reside in <code>/p4/common/bin</code>. The <code>/p4/<instance>/bin</code> directory (e.g. <code>/p4/1/bin</code>) contains scripts or links that are specific to that instance such as wrappers for the p4d executable.</p> </div> <div class="paragraph"> <p>Older versions of the SDP required you to always run important administrative commands using the <code>p4master_run</code> script, and specify fully qualified paths. This script loads environment information from <code>/p4/common/bin/p4_vars</code>, the central environment file of the SDP, ensuring a controlled environment. The <code>p4_vars</code> file includes instance specific environment data from <code>/p4/common/config/p4_<strong><em>instance</em>.</strong>vars</code> e.g. <code>/p4/common/config/p4_1.vars</code>. The <code>p4master_run script</code> is still used when running p4 commands against the server unless you set up your environment first by sourcing p4_vars with the instance as a parameter (for bash shell: <code>source /p4/common/bin/p4_vars 1</code>). Administrative scripts, such as <code>daily_backup.sh</code>, no longer need to be called with <code>p4master_run</code> however, they just need you to pass the instance number to them as a parameter.</p> </div> <div class="paragraph"> <p>When invoking a Perforce command directly on the server machine, use the p4_<strong><em>instance</em></strong> wrapper that is located in <code>/p4/<strong><em>instance</em></strong>/bin</code>. This wrapper invokes the correct version of the p4 client for the instance. The use of these wrappers enables easy upgrades, because the wrapper is a link to the correct version of the p4 client. There is a similar wrapper for the p4d executable, called p4d_<strong><em>instance</em></strong>.</p> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> This wrapper is important to handle case sensitivity in a consistent manner, e.g. when running a Unix server in case-insensitive mode. If you just execut <code>p4d</code> directly when it should be case-insenstive, then you may cause problems, or commands will fail. </td> </tr> </table> </div> <div class="paragraph"> <p>Below are some usage examples for instance 1.</p> </div> <table class="tableblock frame-all grid-all stretch"> <colgroup> <col style="width: 50%;"> <col style="width: 50%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-top"><em>Example</em></th> <th class="tableblock halign-left valign-top"><em>Remarks</em></th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/p4/common/bin/p4master_run 1 /p4/1/bin/p4_1 admin stop</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Run <code>p4 admin stop</code> on instance 1</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/p4/common/bin/live_checkpoint.sh 1</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Take a checkpoint of the live database on instance 1</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/p4/common/bin/p4login 1</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Log in as the perforce user (superuser) on instance 1.</p></td> </tr> </tbody> </table> <div class="paragraph"> <p>Some maintenance scripts can be run from any client workspace, if the user has administrative access to Perforce.</p> </div> </div> <div class="sect3"> <h4 id="_monitoring_sdp_activities">7.1.2. Monitoring SDP activities</h4> <div class="paragraph"> <p>The important SDP maintenance and backup scripts generate email notifications when they complete.</p> </div> <div class="paragraph"> <p>For further monitoring, you can consider options such as:</p> </div> <div class="ulist"> <ul> <li> <p>Making the SDP log files available via a password protected HTTP server.</p> </li> <li> <p>Directing the SDP notification emails to an automated system that interprets the logs.</p> </li> </ul> </div> </div> </div> <div class="sect2"> <h3 id="_core_scripts">7.2. Core Scripts</h3> <div class="paragraph"> <p>The core SDP scripts are those related to checkpoints and other scheduled operations, and all run from <code>/p4/common/bin</code>.</p> </div> <div class="paragraph"> <p>If you <code>source /p4/common/bin/p4_vars <instance></code> then the <code>/p4/common/bin</code> directory will be added to your $PATH.</p> </div> <div class="sect3"> <h4 id="_p4_vars">7.2.1. p4_vars</h4> <div class="paragraph"> <p>Defines the environment variables required by the Perforce server. This script uses a specified instance number as a basis for setting environment variables. It will look for and open the respective p4_<instance>.vars file (see next section).</p> </div> <div class="paragraph"> <p>This script also sets server logging options and configurables.</p> </div> <div class="paragraph"> <p>It is intended to be used by other scripts fro common environment settings, and also by users for setting the environment of their Bash shell.</p> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>source /p4/common/bin/p4_vars 1</pre> </div> </div> </div> <div class="sect3"> <h4 id="_p4_instance_vars">7.2.2. p4_<instance>.vars</h4> <div class="paragraph"> <p>Defines the environment variables for a specific instance, including P4PORT etc.</p> </div> <div class="paragraph"> <p>This script is called by <a href="#_p4_vars">Section 7.2.1, “p4_vars”</a> - it is not intended to be called directly by a user.</p> </div> <div class="paragraph"> <p>For instance <code>1</code>:</p> </div> <div class="literalblock"> <div class="content"> <pre>p4_1.vars</pre> </div> </div> <div class="paragraph"> <p>For instance <code>art</code>:</p> </div> <div class="literalblock"> <div class="content"> <pre>p4_art.vars</pre> </div> </div> <div class="paragraph"> <p><strong>Location</strong>: /p4/common/config</p> </div> </div> <div class="sect3"> <h4 id="_p4master_run">7.2.3. p4master_run</h4> <div class="paragraph"> <p>This is the wrapper script to other SDP scripts. This ensures that the shell environment is loaded from <code>p4_vars</code>. It provides a '-c' flag for silent operation, used in many crontab so that email is sent from the scripts themselves.</p> </div> <div class="paragraph"> <p>This script is somewhat historical, in that most scripts now directly <code>source</code> the <code>p4_vars</code> script directly. It is still occasionally useful.</p> </div> </div> <div class="sect3"> <h4 id="_daily_checkpoint_sh">7.2.4. daily_checkpoint.sh</h4> <div class="paragraph"> <p>This script is configured to run six days a week using crontab. The script:</p> </div> <div class="ulist"> <ul> <li> <p>truncates the journal</p> </li> <li> <p>replays it into the <code>offline_db</code> directory</p> </li> <li> <p>creates a new checkpoint from the resulting database files</p> </li> <li> <p>recreates the <code>offline_db</code> databsae from the new checkpoint.</p> </li> </ul> </div> <div class="paragraph"> <p>This procedure rebalances and compresses the database files in the <code>offline_db</code> directory. These are rotated into the live (<code>root</code>) databse, by the script <a href="#_refresh_p4root_from_offline_db_sh">Section 7.2.10, “refresh_P4ROOT_from_offline_db.sh”</a></p> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>/p4/common/bin/daily_checkpoint.sh <instance> /p4/common/bin/daily_checkpoint.sh 1</pre> </div> </div> </div> <div class="sect3"> <h4 id="_recreate_offline_db_sh">7.2.5. recreate_offline_db.sh</h4> <div class="paragraph"> <p>Recovers the offline_db database from the latest checkpoint and replays any journals since then. If you have a problem with the offline database then it is worth running this script first before running <a href="#_live_checkpoint_sh">Section 7.2.6, “live_checkpoint.sh”</a>, as the latter will stop the server while it is running, which can take hours for a large installation.</p> </div> <div class="paragraph"> <p>Run this script if an error occurs while replaying a journal during daily checkpoint process.</p> </div> <div class="paragraph"> <p>This script recreates offline_db files from the latest checkpoint. If it fails, then check to see if the most recent checkpoint in the <code>/p4/<instance>/checkpoints</code> directory is bad (ie doesn’t look like the right size compared to the others), and if so, delete it and rerun this script. If the error you are getting is that the journal replay failed, then the only option is to run <a href="#_live_checkpoint_sh">Section 7.2.6, “live_checkpoint.sh”</a> script.</p> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>/p4/common/bin/recreate_offline_db.sh <instance> /p4/common/bin/recreate_offline_db.sh 1</pre> </div> </div> </div> <div class="sect3"> <h4 id="_live_checkpoint_sh">7.2.6. live_checkpoint.sh</h4> <div class="paragraph"> <p>This is a fallback option for use when you suspect that the <code>offline_db</code> has become corrupt.</p> </div> <div class="paragraph"> <p>This performs the following actions:</p> </div> <div class="ulist"> <ul> <li> <p>Stops the server</p> </li> <li> <p>Creates a checkpoint from the live database files</p> </li> <li> <p>Recovers the <code>offline_db</code> database from that checkpoint to rebalance and compress the files</p> </li> </ul> </div> <div class="paragraph"> <p>Run this script when creating the server and if an error occurs while replaying a journal during the off-line checkpoint process.</p> </div> <div class="admonitionblock important"> <table> <tr> <td class="icon"> <i class="fa icon-important" title="Important"></i> </td> <td class="content"> Be aware it locks live database for the duration of the checkpoint which can take hours for a large installation (please check the <code>/p4/1/logs/checkpoint.log</code> for the most recent output of <code>daily_backup.sh</code> to see how long checkpoints take to create/restore). </td> </tr> </table> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>/p4/common/bin/live_checkpoint.sh <instance> /p4/common/bin/live_checkpoint.sh 1</pre> </div> </div> </div> <div class="sect3"> <h4 id="_p4verify_sh">7.2.7. p4verify.sh</h4> <div class="paragraph"> <p>Verifies the integrity of the depot files. This script is run by crontab on a regular basis.</p> </div> <div class="paragraph"> <p>It verifies <a href="https://www.perforce.com/manuals/cmdref/Content/CmdRef/p4_verify.html">both shelves and ordinary archive files</a></p> </div> <div class="paragraph"> <p>Any errors in the log file (e.g. <code>/p4/1/logs/p4verify.log</code>) should be handled according to KB articles:</p> </div> <div class="ulist"> <ul> <li> <p><a href="https://community.perforce.com/s/article/3186">MISSING! errors from p4 verify</a></p> </li> <li> <p><a href="https://community.perforce.com/s/article/2404">BAD! error from p4 verify</a></p> </li> </ul> </div> <div class="paragraph"> <p>If in doubt contact <a href="mailto:support@perforce.com">support@perforce.com</a></p> </div> <div class="paragraph"> <p>Our recommendation is that you should expect this to be without error, and you should address errors sooner rather than later. This could involved obliterating unrecoverable errors.</p> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> when run on replicas, this will also append the <code>-t</code> flag to the <code>p4 verify</code> command to ensure that MISSING files are scheduled for transfer. This is useful to keep replicas (includ edge servers) up-to-date. </td> </tr> </table> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>/p4/common/bin/p4verify.sh <instance> /p4/common/bin/p4verify.sh 1</pre> </div> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code> echo "USAGE for p4verify.sh v$Version: p4verify.sh [<instance>] [-nu] [-nr] [-ns] [-nS] [-a] [-recent] [-L <log>] [-v] [-D] or p4verify.sh -h|-man " if [[ $style == -man ]]; then echo -e "DESCRIPTION: This script performs a 'p4 verify' of all submitted and shelved versioned files in depots of all types except 'remote' and 'archive' type depots. If run on a replica, it schedules archive failures for transfer to the replica. OPTIONS: <instance> Specify the SDP instances. If not specified, the SDP_INSTANCE environment variable is used instead. If the instance is not defined by a parameter and SDP_INSTANCE is not defined, p4verify.sh exists immediately with an error message. -nu Specify '-nu' (No Unload) to skip verification of the singleton depot of type 'unload' (if created). The 'unload' depot is verified by default. -nr Specify '-nr' (No Regular) to skip verification of regular submitted archive files. The '-nr' option is not compatible with '-recent'. Regular submitted archive files are verified by default. -ns Specify '-ns' (No Spec Depot) to skip verification of singleton depot of type 'spec' (if created). The 'spec' depot is verified by default. -nS Specify '-nS' (No Shelves) to skip verification of shelved archive files, i.e. to skip the 'p4 verify -qS'. -a Specify '-a' (Archive Depots) to do verification of depots of type 'archive'. Depots of type 'archive' are not verified by default, as archive depots are often physically removed from the server's storage subsystem for long-term cold storage. -recent Specify that only recent changelists should be verified. The \$SDP_RECENT_CHANGES_TO_VERIFY variable defines how many changelists are considered recent; the default is $RecentChangesToVerify. If the default is not appropriate for your site, add \"export SDP_RECENT_CHANGES_TO_VERIFY\" to /p4/common/config/p4_N.vars to change the default for an instance, or to /p4/common/bin/p4_vars to change it globally. If unset, the default is $RecentChangesToVerify. When -recent is used, neither shelves nor files in the unload depot are verified. -v Verbose. Show output of verify attempts, which is suppressed by default. Setting SDP_SHOW_LOG=1 in the shell environment has the same effect as -v. The default behavior of this script is to generate no terminal outpout, but instead to write output into a log file -- see LOGGING below. If '-v' is specified, the generated log is sent to stdout at the end of processing. This flag is not recommended for routine cron operation or for large data sets. -L <log> Specify the log file to use. The default is /p4/N/logs/p4verify.log Log rotation and old log cleanup logic does not apply to log files specified with -L. Thus, using -L is not recommended for routine scheduled operation, e.g. via crontab. -D Set extreme debugging verbosity. HELP OPTIONS: -h Display short help message -man Display man-style help message EXAMPLES: This script is typically called via cron with only the instance parameter as an argument, e.g.: p4verify.sh N LOGGING: This script generates no output by default. All (stdout and stderr) is logged to /p4/N/logs/p4verify.log. The exception is usage errors, which result an error being sent to stderr followed usage info on stdout, followed by an immediate exit. If the '-v' flag is used, the contents of the log are displayed to stdout at the end of processing. EXIT CODES: An exit code of 0 indicates no errors were encounted attempting to perform verifications, AND that all verifications attempted reported no problems. A exit status of 1 indicates that verifications could not be attempted for some reason. A exit status of 2 indicates that verifications were successfully performed, but that problems such as BAD or MISSING files were detected, or else system limits prevented verification. "</code></pre> </div> </div> </div> <div class="sect3"> <h4 id="_p4login">7.2.8. p4login</h4> <div class="paragraph"> <p>Executes a p4 login command, using the administration password configured in <code>mkdirs.cfg</code> and subsequently stored in a text file: <code>/p4/common/config/.p4passwd .p4_<instance>.admin</code></p> </div> <div class="listingblock"> <div class="title">Usage</div> <div class="content"> <pre class="highlight"><code> echo "USAGE for p4login v$Version: p4login [<instance>] [-p <port> | -service] [-automation] [-all] or p4login -h|-man " if [[ "$style" == -man ]]; then echo -e "DESCRIPTION: In its simplest form, this script simply logs in P4USER to P4PORT using the defined password access mechanism. It generates a login ticket for the SDP super user, defined by P4USER when sourcing the SDP standard shell environment. It is called from cron scripts, and so does not normally generate any output. If run on a replica with the -service option, the serviceUser defined for the given replica is logged in. The \$SDP_AUTOMATION_USERS variable can be defined in $P4CCFG/p4_N.vars. If defined, this should contain a comma-delimited list of automation users to be logged in when the -automation option is used. A definition might look like: export SDP_AUTOMATION_USERS=builder,trigger-admin,p4review Login behaviour is affected by external factors: 1. P4AUTH, if defined, affects login behavior on replicas. 2. The auth.id setting, if defined, affects login behaviors (and generally simplifies them). 3. The \$SDP_ALWAYS_LOGIN variable. If set to 1, this causes p4login to always execute a 'p4 login' command to generate a login ticket, even if a 'p4 login -s' test indicates none is needed. By default, the login is skipped if a 'p4 login -s' test indicates a long-term ticket is available that expires 31+days in the future. Add \"export SDP_ALWYAYS_LOGIN=1\" to $P4CCFG/p4_N.vars to change the default for an instance, or to $P4CBIN/p4_vars to change it globally. If unset, the default is 0. 4. If the P4PORT contains an ssl: prefix, the P4TRUST relationship is checked, and if necessary, a p4 trust -f -y is done to establish trust. OPTIONS: <instance> Specify the SDP instances. If not specified, the SDP_INSTANCE environment variable is used instead. If the instance is not defined by a parameter and SDP_INSTANCE is not defined, p4login exists immediately with an error message. -service Specify -service when run on a replica or edge server to login the super user and the replication service user. This option is not compatible with '-p <port>'. -p <port> Specify a P4PORT value to login to, overriding the default defined by P4PORT setting in the environment. If operating on a host other than the master, and auth.id is set, this flag is ignored; the P4TARGET for the replica is used instead. This option is not compatible with '-service'. -automation Specify -automation to login external automation users defined by the \$SDP_AUTOMATION_USERS variable. -v Show ouptput of login attempts, which is suppressed by default. Setting SDP_SHOW_LOG=1 in the shell environment has the same effect as -v. -L <log> Specify the log file to use. The default is /p4/N/logs/p4login.log -d Set debugging verbosity. -D Set extreme debugging verbosity. HELP OPTIONS: -h Display short help message -man Display man-style help message EXAMPLES: 1. Typical usage for automation, with instance SDP_INSTANCE defined in the environment by sourcing p4_vars, and logging in only the super user P4USER to P4PORT: source $P4CBIN/p4_vars abc p4login Login in only P4USER to the specified port, P4MASTERPORT in this example: p4login -p \$P4MASTERPORT Login the super user P4USER, and then login the replication serviceUser for the current ServerID: p4login -service Login external automation users (see SDP_AUTOMATION_USERS above): p4login -automation Login all users: p4login -all Or: p4login -service -automation LOGGING: This script generates no output by default. All (stdout and stderr) is logged to /p4/N/logs/p4login.log. The exception is usage errors, which result an error being sent to stderr followed usage info on stdout, followed by an immediate exit. If the '-v' flag is used, the contents of the log are displayed to stdout at the end of processing. EXIT CODES: An exit code of 0 indicates a valid login ticket exists, while a non-zero exit code indicates a failure to login. "</code></pre> </div> </div> </div> <div class="sect3"> <h4 id="_p4d_instance_init">7.2.9. p4d_<instance>_init</h4> <div class="paragraph"> <p>Starts the Perforce server. Can be called directly or as describe in <a href="#_configuring_automatic_service_start_on_boot">Section 3.2, “Configuring (Automatic) Service Start on Boot”</a></p> </div> <div class="admonitionblock important"> <table> <tr> <td class="icon"> <i class="fa icon-important" title="Important"></i> </td> <td class="content"> Do not use directly if you have configured systemctl for systemd Linux distributions such as CentOS 7.x. This risks database corruption if <code>systemd</code> does not think the service is running when it actually is running (for example on shutdown systemd will just kill processes without waiting for them). </td> </tr> </table> </div> <div class="paragraph"> <p>This script sources <code>/p4/common/bin/p4_vars</code>, then runs <code>/p4/common/bin/p4d_base</code> (<a href="#_p4d_base">Section 7.4.10, “p4d_base”</a>).</p> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>/p4/<instance>/bin/p4d_<instance>_init [ start | stop | status | restart ] /p4/1/bin/p4d_1_init start</pre> </div> </div> </div> <div class="sect3"> <h4 id="_refresh_p4root_from_offline_db_sh">7.2.10. refresh_P4ROOT_from_offline_db.sh</h4> <div class="paragraph"> <p>This script is intended to be used every 1-3 months to ensure that your live (<code>root</code>) database files are defragmented.</p> </div> <div class="paragraph"> <p>It will:</p> </div> <div class="ulist"> <ul> <li> <p>stop p4d</p> </li> <li> <p>truncate/rotate live journal</p> </li> <li> <p>replay journals to offline_db</p> </li> <li> <p>switch the links between <code>root</code> and <code>offline_db</code></p> </li> <li> <p>restart p4d</p> </li> </ul> </div> <div class="paragraph"> <p>It also knows how to do similar processes on edge servers and standby servers or other replicas.</p> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>/p4/common/bin/refresh_P4ROOT_from_offline_db.sh <instance> /p4/common/bin/refresh_P4ROOT_from_offline_db.sh 1</pre> </div> </div> </div> <div class="sect3"> <h4 id="_run_if_master_sh">7.2.11. run_if_master.sh</h4> <div class="paragraph"> <p>See <a href="#_run_if_masteredgereplica_sh">Section 7.2.14, “run_if_master/edge/replica.sh”</a></p> </div> </div> <div class="sect3"> <h4 id="_run_if_edge_sh">7.2.12. run_if_edge.sh</h4> <div class="paragraph"> <p>See <a href="#_run_if_masteredgereplica_sh">Section 7.2.14, “run_if_master/edge/replica.sh”</a></p> </div> </div> <div class="sect3"> <h4 id="_run_if_replica_sh">7.2.13. run_if_replica.sh</h4> <div class="paragraph"> <p>See <a href="#_run_if_masteredgereplica_sh">Section 7.2.14, “run_if_master/edge/replica.sh”</a></p> </div> </div> <div class="sect3"> <h4 id="_run_if_masteredgereplica_sh">7.2.14. run_if_master/edge/replica.sh</h4> <div class="paragraph"> <p>The SDP uses wrapper scripts in the crontab: <code>run_if_master.sh</code>, <code>run_if_edge.sh</code>, <code>run_if_replica.sh</code>. We suggest you ensure these are working as desired, e.g.</p> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>/p4/common/bin/run_if_master.sh 1 echo yes /p4/common/bin/run_if_replica.sh 1 echo yes /p4/common/bin/run_if_edge.sh 1 echo yes</pre> </div> </div> <div class="paragraph"> <p>It is important to ensure these are returning the valid results for the server machine you are on.</p> </div> <div class="paragraph"> <p>Any issues with these scripts are likely configuration issues with <code>/p4/common/config/p4_1.vars</code> (for instance <code>1</code>)</p> </div> </div> </div> <div class="sect2"> <h3 id="_more_server_scripts">7.3. More Server Scripts</h3> <div class="paragraph"> <p>These scripts are helpful components of the SDP that run on the server, but are not included in the default crontab schedules.</p> </div> <div class="sect3"> <h4 id="_upgrade_sh">7.3.1. upgrade.sh</h4> <div class="paragraph"> <p>Runs a typical upgrade process, once new p4 and p4d binaries are available in <code>/p4/common/bin</code> - saved as <code>p4</code> and <code>p4d</code> respectively (overwriting any existing files with those names).</p> </div> <div class="paragraph"> <p>This script will:</p> </div> <div class="ulist"> <ul> <li> <p>Rotate the journal (to provide a clean recovery point)</p> </li> <li> <p>Apply all necessary journals to offline_db</p> </li> <li> <p>Stop the server</p> </li> <li> <p>Create an appropriately versioned link for new p4/p4d/p4broker etc</p> </li> <li> <p>Link those into <code>/p4/1/bin</code> (per instance)</p> </li> <li> <p>Run <code>p4d -xu</code> on live and offline_db to perform database upgrades (in a version aware manner, for example pre 2018.2 servers are treated differently to 2018.2 or later servers)</p> </li> <li> <p>Restart server instance</p> </li> </ul> </div> <div class="paragraph"> <p>The links for different versions of <code>p4d</code> are described in <a href="#_p4d_versions_and_links">Section A.1.3, “P4D versions and links”</a></p> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> it is not recommended to do the linking manually (although of course possible, but surprisingly easy to get wrong!). </td> </tr> </table> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>/p4/common/bin/upgrade.sh <instance> /p4/common/bin/upgrade.sh 1</pre> </div> </div> </div> <div class="sect3"> <h4 id="_p4_crontab">7.3.2. p4.crontab</h4> <div class="paragraph"> <p>Contains crontab entries to run the server maintenance scripts.</p> </div> <div class="paragraph"> <p><strong>Location</strong>: /p4/sdp/Server/Unix/p4/common/etc/cron.d</p> </div> </div> <div class="sect3"> <h4 id="_verify_sdp_sh">7.3.3. verify_sdp.sh</h4> <div class="paragraph"> <p>Does basic verification of SDP setup.</p> </div> <div class="listingblock"> <div class="title">Usage</div> <div class="content"> <pre class="highlight"><code> echo "USAGE for verify_sdp.sh v$Version: verify_sdp.sh [<instance>] [-online] [-si] [-L <log>|off ] [-D] or verify_sdp.sh -h|-man " echo -e "DESCRIPTION: This script verifies the current SDP setup for the specified instance. Useful if you change anything, particularly after an SDP upgrade. OPTIONS: <instance> Specify the SDP instances. If not specified, the SDP_INSTANCE environment variable is used instead. If the instance is not defined by a parameter and SDP_INSTANCE is not defined, exits immediately with an error message. -online Online mode. Does additional checks that require P4D to be online. -si Silent mode. Does not display stdout at the end of processing. -L <log> Specify the log file to use. The default is /p4/N/logs/verify_sdp.log The special value 'off' disables logging to a file. -D Set extreme debugging verbosity. HELP OPTIONS: -h Display short help message -man Display man-style help message EXAMPLES: This script is typically called after SDP update with only the instance name or number as an argument, e.g.: verify_sdp.sh 1 Or, if used from automation already doing its own logging, use -L off: verify_sdp.sh 1 -L off LOGGING: This script generates a log file and also displays it to stdout at the end of processing. By default, the log is: /p4/N/logs/verify_sdp.log. The exception is usage errors, which result an error being sent to stderr followed usage info on stdout, followed by an immediate exit. If the '-si' (silent) flag is used, the log is generated, but its contents are not displayed to stdout at the end of processing. EXIT CODES: An exit code of 0 indicates no errors were encounted attempting to perform verifications, and that all checks verified cleanly. "</code></pre> </div> </div> </div> </div> <div class="sect2"> <h3 id="_other_scripts_and_files">7.4. Other Scripts and Files</h3> <div class="paragraph"> <p>The following table describes other files in the SDP distribution. These files are usually not invoked directly by you; rather, they are invoked by higher-level scripts.</p> </div> <div class="sect3"> <h4 id="_backup_functions_sh">7.4.1. backup_functions.sh</h4> <div class="paragraph"> <p>This contains lots of standard Bash functions which are used in other scripts.</p> </div> <div class="paragraph"> <p>It is <strong>sourced</strong> (<code>source /p4/common/bin/backup_functions.sh</code>) by most of the other scripts in order to use the common shared functions and to avoid duplication.</p> </div> <div class="paragraph"> <p>It is not intendend to be called directly by the user.</p> </div> </div> <div class="sect3"> <h4 id="_broker_rotate_sh">7.4.2. broker_rotate.sh</h4> <div class="paragraph"> <p>This script rotates the broker log file on an instance that only has the broker running.</p> </div> <div class="paragraph"> <p>It can be added to a crontab for e.g. daily log rotation.</p> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>/p4/common/bin/broker_rotate.sh <instance> /p4/common/bin/broker_rotate.sh 1</pre> </div> </div> </div> <div class="sect3"> <h4 id="_edge_dump_sh">7.4.3. edge_dump.sh</h4> <div class="paragraph"> <p>This script is designed to create a seed checkpoint for an Edge server.</p> </div> <div class="paragraph"> <p>An edge server is naturally filtered, with certain database tables (e.g. db.have) excluded. In addition to implicit filtering, the server spec may specify additional tables to be excluded, e.g. by using the ArchiveDataFilter field of the server spec.</p> </div> <div class="paragraph"> <p>The script requires the SDP instance and the edge ServerID.</p> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>/p4/common/bin/edge_dump.sh <instance> <edge server id> /p4/common/bin/edge_dump.sh 1 p4d_edge_syd</pre> </div> </div> <div class="paragraph"> <p>It will output the full path of the checkpoint to be copied to the edge server and used with <a href="#_recover_edge_sh">Section 7.4.22, “recover_edge.sh”</a></p> </div> </div> <div class="sect3"> <h4 id="_edge_vars">7.4.4. edge_vars</h4> <div class="paragraph"> <p>This file is sourced by scripts that work on edge servers.</p> </div> <div class="paragraph"> <p>It sets the correct list db.* files that are edge-specific in the federated architecture. This version is dependent on the version of p4d in use.</p> </div> <div class="paragraph"> <p>It is not intended for users to call directly.</p> </div> </div> <div class="sect3"> <h4 id="_edge_shelf_replicate_sh">7.4.5. edge_shelf_replicate.sh</h4> <div class="paragraph"> <p>This script is intended to be run on an edge server and will ensure that all shelves are replicated to that edge server (by running <code>p4 print</code> on them).</p> </div> <div class="paragraph"> <p>Only use if directed to by support/consulting.</p> </div> </div> <div class="sect3"> <h4 id="_load_checkpoint_sh">7.4.6. load_checkpoint.sh</h4> <div class="paragraph"> <p>Loads a checkpoint for commit/edge/replica instance.</p> </div> <div class="listingblock"> <div class="title">Usage</div> <div class="content"> <pre class="highlight"><code> echo "USAGE for $THISSCRIPT v$Version: $THISSCRIPT <checkpoint> [-i <instance>] [-s <ServerID>] [-c] [-l] [-r] [-b] [-y] [-L <log>] [-si] [-v<n>] [-D] or $THISSCRIPT [-h|-man|-V] " if [[ $style == -man ]]; then echo -e " DESCRIPTION: This script loads a specified checkpoint into /p4/N/root and /p4/N/offline_db, where 'N' is the SDP instance name. At the start of processing, preflight checks are done. Preflight checks include: * The specified checkpoint and corresponding *.md5 file must exist. * The \$P4ROOT/server.id file must exist, unless '-s' is specified. * The \$P4ROOT/license file must exist, unless '-l' is specified. * Basic SDP structure and key files must exist. If the preflight passes, the p4d_N service is shutdown, and also the p4broker_N service is shutdown if configured. Next, the specified checkpoint is loaded. Upon completion, the Helix Core server process, p4d_N, is started. If the server to be started is a replica, the serviceUser configured for the replica is logged into the P4TARGET server. Any needed 'p4 trust' and 'p4 login' commands are done to enable replication. Note that this part of the processing will fail if the correct super user password is not stored in the standard SDP password file, /p4/common/config/.p4passwd.p4_N.admin After starting the server, a local 'p4 trust' is done if needed, and then a 'p4login -service -v' and 'p4login -v'. By default, the p4d_N service is started, but the p4broker_N service is not. Specify '-b' to restart both services. ARGUMENTS AND OPTIONS: <checkpoint> Specify the path to the checkpoint file to load. The file may be a compressed or uncompressed checkpoint, and it may bea case sensitive or case-insensitive checkpoint. The checkpoint file must have a corresponding *.md5 checksum file in the same directory, with one of two name variations: If the checkpoint file is /somewhere/foo.gz, the checksum file may be named /somewhere/foo.gz.md5 or /somewhere/foo.md5. -i <instance> Specify the SDP instance. This can be omitted if SDP_INSTANCE is already defined. -s <ServerID> Specify the ServerID. This value is written into \$P4ROOT/server.id file. If the \$P4ROOT/server.id file exists, value in the file must match the value specified with this flag. If no \$P4ROOT/server.id file exists, this flag is required. -c Specify that SSL certificates are required, and not to be generated with 'p4d_N -Gc'. By default, if '-c' is not supplied and SSL certs are not availalbe, certs are generated automatically with 'p4d_N -Gc'. -l Specify that the server is to start without a license file. By default, if there is no \$P4ROOT/license file, this script will abort. Note that if '-l' is specified and a license file is actually needed, the attempt this script makes to start the server after loading the checkpoint will fail. -r Specify '-r' to replay only to P4ROOT. By default, this script replays both to P4ROOT and the offline_db. -b Specify '-b' to start the a p4broker process (if configured). By default the p4d process is started after loading the checkpoint, but the p4broker process is not. This can be useful to ensure the human administrator has an opportunity to do sanity checks before enabling the broker to allow access by end users (if the broker is deployed for this usage). -y Use the '-y' flag to bypass an interactive warning and confirmation prompt. -v<n> Set verbosity 1-5 (-v1 = quiet, -v5 = highest). The default is 5. -L <log> Specify the path to a log file. By default, all output (stdout and stderr) goes to: /p4/<instance>/logs/${THISSCRIPT%.sh}.<timestamp>.log NOTE: This script is self-logging. That is, output displayed on the screen is simultaneously captured in the log file. Do not run this script with redirection operators like '> log' or '2>&1', and do not use 'tee.' -si Operate silently. All output (stdout and stderr) is redirected to the log only; no output appears on the terminal. -D Set extreme debugging verbosity. HELP OPTIONS: -h Display short help message -man Display man-style help message -V Dispay version info for this script and its libraries. FILES: EXAMPLES: Sample Usage (bash syntax): nohup $P4CBIN/load_checkpoint.sh /p4/1/checkpoints/p4_1.ckp.4025.gz -i 1 -y -si < /dev/null > /dev/null 2>&1 & Then, monitor with: tail -f \$(ls -t \$LOGS/load_checkpoint.*.log|head -1)\\n "</code></pre> </div> </div> </div> <div class="sect3"> <h4 id="_gen_default_broker_cfg_sh">7.4.7. gen_default_broker_cfg.sh</h4> <div class="paragraph"> <p>Generate an SDP instance-specific variant of the generic P4Broker config file. Display to standard output.</p> </div> <div class="paragraph"> <p>Usage:</p> </div> <div class="literalblock"> <div class="content"> <pre>cd /p4/common/bin gen_default_broker_cfg.sh 1 > /tmp/p4broker.cfg.ToBeReviewed</pre> </div> </div> <div class="paragraph"> <p>The final p4broker.cfg should end up here:</p> </div> <div class="literalblock"> <div class="content"> <pre>/p4/common/config/p4_${SDP_INSTANCE}.${SERVERID}.broker.cfg</pre> </div> </div> </div> <div class="sect3"> <h4 id="_journal_watch_sh">7.4.8. journal_watch.sh</h4> <div class="paragraph"> <p>This script will check diskspace available to P4JOURNAL and trigger a journal rotation based on specified thresholds. This is useful in case you are in danger of running out of disk space and your rotated journal files are stored on a separate partition than the active journal.</p> </div> <div class="paragraph"> <p>This script is using the following external variables:</p> </div> <div class="ulist"> <ul> <li> <p>SDP_INSTANCE - The instance of Perforce that is being backed up. If not set in environment, pass in as argument to script.</p> </li> <li> <p>P4JOURNALWARN - Amount of space left (K,M,G,%) before min journal space where an email alert is sent</p> </li> <li> <p>P4JOURNALWARNALERT - Send an alert if warn threshold is reached (true/false, default: false)</p> </li> <li> <p>P4JOURNALROTATE - Amount of space left (K,M,G,%) before min journal space to trigger a journal rotation</p> </li> <li> <p>P4OVERRIDEKEEPJNL - Allow script to temporarily override KEEPJNL to retain enough journals to replay against oldest checkpoint (true/false, default: false)</p> </li> </ul> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>/p4/common/bin/journal_watch.sh <P4JOURNALWARN> <P4JOURNALWARNALERT> <P4JOURNALROTATE> <P4OVERRIDEKEEPJNL (Optional)></pre> </div> </div> <div class="paragraph"> <div class="title">Examples</div> <p>Run from CLI that will warn via email if less than 20% is available and rotate journal when less than 10% is available</p> </div> <div class="literalblock"> <div class="content"> <pre>./journal_watch.sh 20% TRUE 10% TRUE</pre> </div> </div> <div class="paragraph"> <p>Cron job that will warn via email if less than 20% is available and rotate journal when less than 10% is available</p> </div> <div class="literalblock"> <div class="content"> <pre>30 * * * * [ -e /p4/common/bin ] && /p4/common/bin/run_if_master.sh ${INSTANCE} /p4/common/bin/journal_watch.sh ${INSTANCE} 20\% TRUE 10\% TRUE</pre> </div> </div> </div> <div class="sect3"> <h4 id="_kill_idle_sh">7.4.9. kill_idle.sh</h4> <div class="paragraph"> <p>Runs <code>p4 monitor terminate</code> on all processes showing in the output of <code>p4 monitor show</code> that are in the IDLE state.</p> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>/p4/common/bin/kill_idle.sh <instance> /p4/common/bin/kill_idle.sh 1</pre> </div> </div> </div> <div class="sect3"> <h4 id="_p4d_base">7.4.10. p4d_base</h4> <div class="paragraph"> <p>This is the script to start/stop/restart the <code>p4d</code> instance.</p> </div> <div class="paragraph"> <p>It is called by <code>p4d_<instance>_init</code> script (and thus also <code>systemctl</code> on systemd Linux distributions)</p> </div> <div class="paragraph"> <p>It ensures appropriate parameters are specified for journal/log and other variables.</p> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>/p4/common/bin/p4d_base <instance> [ start|stop|admin_stop|status|restart|force_start ] /p4/common/bin/p4d_base 1 start</pre> </div> </div> </div> <div class="sect3"> <h4 id="_p4broker_base">7.4.11. p4broker_base</h4> <div class="paragraph"> <p>Very similar to <a href="#_p4d_base">Section 7.4.10, “p4d_base”</a> but for the <code>p4broker</code> service instance.</p> </div> <div class="paragraph"> <p>See <a href="https://www.perforce.com/manuals/p4dist/Content/P4Dist/chapter.broker.html">p4broker in SysAdmin Guide</a></p> </div> </div> <div class="sect3"> <h4 id="_p4ftpd_base">7.4.12. p4ftpd_base</h4> <div class="paragraph"> <p>Very similar to <a href="#_p4d_base">Section 7.4.10, “p4d_base”</a> but for the <code>p4ftp</code> service instance.</p> </div> <div class="paragraph"> <p>This product is very seldom used these days!</p> </div> <div class="paragraph"> <p>See <a href="https://www.perforce.com/manuals/p4ftp/index.html">P4FTP Installation Guide.</a></p> </div> </div> <div class="sect3"> <h4 id="_p4p_base">7.4.13. p4p_base</h4> <div class="paragraph"> <p>Very similar to <a href="#_p4d_base">Section 7.4.10, “p4d_base”</a> but for the <code>p4p</code> (P4 Proxy) service instance.</p> </div> <div class="paragraph"> <p>See <a href="https://www.perforce.com/manuals/p4dist/Content/P4Dist/chapter.proxy.html">p4proxy in SysAdmin Guide</a></p> </div> </div> <div class="sect3"> <h4 id="_p4pcm_pl">7.4.14. p4pcm.pl</h4> <div class="paragraph"> <p>This utility removes files in the proxy cache if the amount of free disk space falls below the low threshold.</p> </div> <div class="listingblock"> <div class="title">Usage</div> <div class="content"> <pre class="highlight"><code> print "\nUsage:\n $main::ThisScript [-d \"proxy cache dir\"] [-tlow <low_threshold>] [-thigh <high_threshold>] [-n] or $main::ThisScript -h This utility removes files in the proxy cache if the amount of free disk space falls below the low threshold (default 10GB). It removes files (oldest first) until the high threshold is (default 20GB) is reached. Specify the thresholds in kilobyte units (kb). The '-d \"proxy cache dir\"' argument is required unless \$P4PCACHE is defined, in which case it is used. The log is \$LOGS/p4pcm.log if \$LOGS is defined, else p4pcm.log in the current directory. Use '-n' to show what files would be removed. ";</code></pre> </div> </div> </div> <div class="sect3"> <h4 id="_p4review_py">7.4.15. p4review.py</h4> <div class="paragraph"> <p>Sends out email containing the change descriptions to users who are configured as reviewers for affected files (done by setting the Reviews: field in the user specification). This script is a version of the <code>p4review.py</code> script that is available on the Perforce Web site, but has been modified to use the server instance number. It relies on a configuration file in <code>/p4/common/config</code>, called <code>p4_<instance>.p4review.cfg</code>. On Windows, a driver called <code>run_p4review.cmd</code>, located in the same directory, allows you to run the review daemon through the <a href="http://en.wikipedia.org/wiki/Task_Scheduler">Windows scheduler</a>.</p> </div> <div class="paragraph"> <p>This is not required if you have installed Swarm which also performs notification functions and is easier for users to configure.</p> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>/p4/common/bin/p4review.py # Uses config file as above</pre> </div> </div> </div> <div class="sect3"> <h4 id="_p4review2_py">7.4.16. p4review2.py</h4> <div class="paragraph"> <p>Enhanced version of <a href="#_p4review_py">Section 7.4.15, “p4review.py”</a></p> </div> <div class="olist arabic"> <ol class="arabic"> <li> <p>Run p4review2.py --sample-config > p4review.conf</p> </li> <li> <p>Edit the file p4review.conf</p> </li> <li> <p>Add a crontab similar to this:</p> <div class="ulist"> <ul> <li> <p>* * * * python2.7 /path/to/p4review2.py -c /path/to/p4review.conf</p> </li> </ul> </div> </li> </ol> </div> <div class="paragraph"> <p>Features:</p> </div> <div class="ulist"> <ul> <li> <p>Prevent multiple copies running concurrently with a simple lock file.</p> </li> <li> <p>Logging support built-in.</p> </li> <li> <p>Takes command-line options.</p> </li> <li> <p>Configurable subject and email templates.</p> </li> <li> <p>Can (optionally) include URLs for changelists/jobs. Examples for P4Web included.</p> </li> <li> <p>Use P4Python when available and use P4 (the CLI) as a fallback.</p> </li> <li> <p>Option to send a <em>single</em> email per user per invocation instead of multiple ones.</p> </li> <li> <p>Reads config from a INI-like file using ConfigParser</p> </li> <li> <p>Have command line options that overrides environment variables.</p> </li> <li> <p>Handles unicode-enabled server <strong>and</strong> non-ASCII characters on a non-unicode-enabled server.</p> </li> <li> <p>Option to opt-in (--opt-in-path) reviews globally (for migration from old review daemon).</p> </li> <li> <p>Configurable URLs for changes/jobs/users (for swarm).</p> </li> <li> <p>Able to limit the maximum email message size with a configurable.</p> </li> <li> <p>SMTP auth and TLS (not SSL) support.</p> </li> <li> <p>Handles P4 auth (optional, not recommended!).</p> </li> </ul> </div> </div> <div class="sect3"> <h4 id="_p4sanity_check_sh">7.4.17. p4sanity_check.sh</h4> <div class="paragraph"> <p>This is a simple script to run:</p> </div> <div class="ulist"> <ul> <li> <p>p4 set</p> </li> <li> <p>p4 info</p> </li> <li> <p>p4 changes -m 10</p> </li> </ul> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>/p4/common/bin/p4sanity_check.sh <instance> /p4/common/bin/p4sanity_check.sh 1</pre> </div> </div> </div> <div class="sect3"> <h4 id="_p4web_base">7.4.18. p4web_base</h4> <div class="paragraph"> <p>Very similar to <a href="#_p4d_base">Section 7.4.10, “p4d_base”</a> but for the <code>p4web</code> service instance.</p> </div> <div class="paragraph"> <p>This product is very seldom used these days - since it has been replaced by Swarm.</p> </div> </div> <div class="sect3"> <h4 id="_p4dstate_sh">7.4.19. p4dstate.sh</h4> <div class="paragraph"> <p>This is a trouble-shooting script for use when directed by support, e.g. in situations such as server hanging, major locking problems etc.</p> </div> <div class="paragraph"> <p>It is an "SDP-aware" version of the <a href="https://community.perforce.com/s/article/15261">standard p4dstate.sh</a> so that it only requires the SDP instance to be specified as a parameter (since the location of logs etc are defined by SDP).</p> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>sudo /p4/common/bin/p4dstate.sh <instance> sudo /p4/common/bin/p4dstate.sh 1</pre> </div> </div> </div> <div class="sect3"> <h4 id="_ps_functions_sh">7.4.20. ps_functions.sh</h4> <div class="paragraph"> <p>Common functions for using 'ps' to check on process ids. Not intended to be called directly but just to be sourced by other scripts.</p> </div> <div class="literalblock"> <div class="content"> <pre>get_pids ($exe)</pre> </div> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>Call with an exe name, e.g. /p4/1/bin/p4web_1</pre> </div> </div> <div class="literalblock"> <div class="title">Examples</div> <div class="content"> <pre>p4web_pids=$(get_pids $P4WEBBIN) p4broker_pids=$(get_pids $P4BROKERBIN)</pre> </div> </div> </div> <div class="sect3"> <h4 id="_purge_revisions_sh">7.4.21. purge_revisions.sh</h4> <div class="paragraph"> <p>This script will allow you to archive files and optionally purge files based on a configurable number of days and minimum revisions that you want to keep. This is useful if you want to keep a certain number of days worth of files instead of a specific number of revisions.</p> </div> <div class="paragraph"> <p>Note: If you run this script with purge mode disabled, and then enable it after the fact, all previously archived files specified in the configuration file will be purged if the configured criteria is met.</p> </div> <div class="paragraph"> <p>Prior to running this script, you may want to disable server locks for archive to reduce impact to end users.</p> </div> <div class="paragraph"> <p><a href="https://www.perforce.com/perforce/doc.current/manuals/cmdref/Content/CmdRef/configurables.configurables.html#server.locks.archive" class="bare">https://www.perforce.com/perforce/doc.current/manuals/cmdref/Content/CmdRef/configurables.configurables.html#server.locks.archive</a></p> </div> <div class="paragraph"> <p>Parameters:</p> </div> <div class="ulist"> <ul> <li> <p>SDP_INSTANCE - The instance of Perforce that is being backed up. If not set in environment, pass in as argument to script.</p> </li> <li> <p>P4_ARCHIVE_CONFIG - The location of the config file used to determine retention. If not set in environment, pass in as argument to script. This can be stored on a physical disk or somewhere in perforce.</p> </li> <li> <p>P4_ARCHIVE_DEPOT - Depot to archive the files in (string)</p> </li> <li> <p>P4_ARCHIVE_REPORT_MODE - Do not archive revisions; report on which revisions would have been archived (bool - default: true)</p> </li> <li> <p>P4_ARCHIVE_TEXT - Archive text files (or other revisions stored in delta format, such as files of type binary+D) (bool - default: false)</p> </li> <li> <p>P4_PURGE_MODE - Enables purging of files after they are archived (bool - default: false)</p> </li> </ul> </div> <div class="paragraph"> <div class="title">Config File Format</div> <p>The config file should contain a list of file paths, number of days and minimum of revisions to keep in a tab delimited format.</p> </div> <div class="literalblock"> <div class="content"> <pre><PATH> <DAYS> <MINIMUM REVISIONS></pre> </div> </div> <div class="paragraph"> <p>Example:</p> </div> <div class="literalblock"> <div class="content"> <pre>//test/1.txt 10 1 //test/2.txt 1 3 //test/3.txt 10 10 //test/4.txt 30 3 //test/5.txt 30 8</pre> </div> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>/p4/common/bin/purge_revisions.sh <SDP_INSTANCE> <P4_ARCHIVE_CONFIG> <P4_ARCHIVE_DEPOT> <P4_ARCHIVE_REPORT_MODE (Optional)> 4_ARCHIVE_TEXT (Optional)> <P4_PURGE_MODE (Optional)></pre> </div> </div> <div class="paragraph"> <div class="title">Examples</div> <p>Run from CLI that will archive files as defined in the config file</p> </div> <div class="literalblock"> <div class="content"> <pre>./purge_revisions.sh 1 /p4/common/config/p4_1.p4purge.cfg archive FALSE</pre> </div> </div> <div class="paragraph"> <p>Cron job that will will archive files as defined in the config file, including text files</p> </div> <div class="literalblock"> <div class="content"> <pre>30 0 * * * [ -e /p4/common/bin ] && /p4/common/bin/run_if_master.sh ${INSTANCE} /p4/common/bin/purge_revisions.sh $NSTANCE} /p4/common/config/p4_1.p4purge.cfg archive FALSE FALSE</pre> </div> </div> </div> <div class="sect3"> <h4 id="_recover_edge_sh">7.4.22. recover_edge.sh</h4> <div class="paragraph"> <p>This script is designed to rebuild an Edge server from a seed checkpoint from the master WHILE KEEPING THE EXISTING EDGE SPECIFIC DATA.</p> </div> <div class="paragraph"> <p>You have to first copy the seed checkpoint from the master, created with <a href="#_edge_dump_sh">Section 7.4.3, “edge_dump.sh”</a>, to the edge server before running this script. (Alternately, a full checkpoint from the master can be used so long as the edge server spec does not specify any filtering, e.g. does not use ArchiveDataFilter.)</p> </div> <div class="paragraph"> <p>Then run this script on the Edge server host with the instance number and full path of the master seed checkpoint as parameters.</p> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>/p4/common/bin/recover_edge.sh <instance> <absolute path to checkpoint> /p4/common/bin/recover_edge.sh 1 /p4/1/checkpoints/p4_1.edge_syd.seed.ckp.9188.gz</pre> </div> </div> </div> <div class="sect3"> <h4 id="_replica_cleanup_sh">7.4.23. replica_cleanup.sh</h4> <div class="paragraph"> <p>This script performs the following actions for a replica:</p> </div> <div class="ulist"> <ul> <li> <p>rotate logs</p> </li> <li> <p>remove old checkpoints and journals</p> </li> <li> <p>remove old logs</p> </li> </ul> </div> <div class="paragraph"> <p>It is a convenenience script for occasional use.</p> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>/p4/common/bin/replica_cleanup.sh <instance> /p4/common/bin/replica_cleanup.sh 1</pre> </div> </div> </div> <div class="sect3"> <h4 id="_replica_status_sh">7.4.24. replica_status.sh</h4> <div class="paragraph"> <p>This script is regularly run by crontab on a replica or edge (using <a href="#_run_if_replica_sh">Section 7.2.13, “run_if_replica.sh”</a>)</p> </div> <div class="literalblock"> <div class="content"> <pre>0 8 * * * [ -e /p4/common/bin ] && /p4/common/bin/run_if_replica.sh ${INSTANCE} /p4/common/bin/replica_status.sh ${INSTANCE} > /dev/null 0 8 * * * [ -e /p4/common/bin ] && /p4/common/bin/run_if_edge.sh ${INSTANCE} /p4/common/bin/replica_status.sh ${INSTANCE} > /dev/null</pre> </div> </div> <div class="paragraph"> <p>It performs a <code>p4 pull -lj</code> command on the replica to report current replication status, and emails this to the standard SDP administrator email on a daily basis. This is useful for monitoring purposes to detect replica lag or similar problems.</p> </div> <div class="paragraph"> <p>If you are using enhance monitoring such as <a href="https://github.com/perforce/p4prometheus">p4prometheus</a> then this script may not be required.</p> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>/p4/common/bin/replica_status.sh <instance> /p4/common/bin/replica_status.sh 1</pre> </div> </div> </div> <div class="sect3"> <h4 id="_request_replica_checkpoint_sh">7.4.25. request_replica_checkpoint.sh</h4> <div class="paragraph"> <p>This script is intended to be run on a standby replica. It essentially just calls 'p4 admin checkpoint -Z' to reqeust a checkpoint and exits. The actual checkpoint is created on the next journal rotation on the master.</p> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>/p4/common/bin/request_replica_checkpoint.sh <instance> /p4/common/bin/request_replica_checkpoint.sh 1</pre> </div> </div> </div> <div class="sect3"> <h4 id="_rotate_journal_sh">7.4.26. rotate_journal.sh</h4> <div class="paragraph"> <p>This script is a convenience script to perform the following actions for the specified instance (single parameter):</p> </div> <div class="ulist"> <ul> <li> <p>rotate live journal</p> </li> <li> <p>replay it to the <code>offline_db</code></p> </li> <li> <p>rotate logs files according to the settings in <code>p4_vars</code> for things like <code>KEEP_LOGS</code></p> </li> </ul> </div> <div class="paragraph"> <p>It is not often used.</p> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>/p4/common/bin/rotate_journal.sh <instance> /p4/common/bin/rotate_journal.sh 1</pre> </div> </div> </div> <div class="sect3"> <h4 id="_sync_replica_sh">7.4.27. sync_replica.sh</h4> <div class="paragraph"> <p>This script is included in the standard crontab for a replica.</p> </div> <div class="paragraph"> <p>It runs <code>rsync</code> to mirror the <code>/p4/1/checkpoints</code> (assumings instance <code>1</code>) directory to the replica machine.</p> </div> <div class="paragraph"> <p>It then uses the latest checkpoint in that directory to update the local <code>offline_db</code> directory for the replica.</p> </div> <div class="paragraph"> <p>This ensures that the replica can be quickly and easily reseeded if required without having to first copy checkpoints locally (which can take hours over slow WAN links).</p> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>/p4/common/bin/sync_replica.sh <instance> /p4/common/bin/sync_replica.sh 1</pre> </div> </div> </div> <div class="sect3"> <h4 id="_templates_directory">7.4.28. templates directory</h4> <div class="paragraph"> <p>This sub-directory of <code>/p4/common/bin</code> contains some files which can be used as templates for new commands if you wish:</p> </div> <div class="ulist"> <ul> <li> <p>template.pl - Perl</p> </li> <li> <p>template.py - Python</p> </li> <li> <p>template.py.cfg - config file for python</p> </li> <li> <p>template.sh - Bash</p> </li> </ul> </div> <div class="paragraph"> <p>They are not intended to be run directly.</p> </div> </div> <div class="sect3"> <h4 id="_update_limits_py">7.4.29. update_limits.py</h4> <div class="paragraph"> <p>This is a Python script which is intended to be called from a crontab entry one per hour.</p> </div> <div class="paragraph"> <p>It ensures that all current users are added to the <code>limits</code> group. This makes it easy for an administrator to configure global limits on values such as MaxScanRows, MaxSearchResults etc. This can reduce load on a heavily loaded instance.</p> </div> <div class="paragraph"> <p>For more information:</p> </div> <div class="ulist"> <ul> <li> <p><a href="https://community.perforce.com/s/article/2529">Maximising Perforce Helix Core Performance</a></p> </li> <li> <p><a href="https://community.perforce.com/s/article/2521">Multiple MaxScanRows and similar values</a></p> </li> </ul> </div> <div class="literalblock"> <div class="title">Usage</div> <div class="content"> <pre>/p4/common/bin/update_limits.py <instance> /p4/common/bin/update_limits.py 1</pre> </div> </div> </div> </div> </div> </div> <div class="sect1"> <h2 id="_sdp_package_contents">Appendix A: SDP Package Contents</h2> <div class="sectionbody"> <div class="paragraph"> <p>The directory structure of the SDP is shown below in Figure 1 - SDP Package Directory Structure. This includes all SDP files, including documentation and maintenance scripts. A subset of these files are deployed to server machines during the installation process.</p> </div> <div class="literalblock"> <div class="content"> <pre>sdp doc Server (Core SDP Files) Unix setup (unix specific setup) p4 common bin (Backup scripts, etc) triggers (Example triggers) config etc cron.d init.d lib test setup (cross platform setup - typemap, configure, etc) test (automated test scripts)</pre> </div> </div> <div class="paragraph"> <p>Figure 1 - SDP Package Directory Structure</p> </div> <div class="sect2"> <h3 id="_volume_layout_and_server_planning">A.1. Volume Layout and Server Planning</h3> <div class="paragraph"> <p>Figure 2: SDP Runtime Structure and Volume Layout, viewed from the top down, displays a Perforce <em>application</em> administrator’s view of the system, which shows how to navigate the directory structure to find databases, log files, and versioned files in the depots. Viewed from the bottom up, it displays a Perforce <em>system</em> administrator’s view, emphasizing the physical volume where Perforce data is stored.</p> </div> <div class="sect3"> <h4 id="_memory_and_cpu">A.1.1. Memory and CPU</h4> <div class="paragraph"> <p>Make sure the server has enough memory to cache the <strong>db.rev</strong> database file and to prevent the server from paging during user queries. Maximum performance is obtained if the server has enough memory to keep all of the database files in memory.</p> </div> <div class="paragraph"> <p><strong>Below are some approximate guidelines for</strong> allocating memory.</p> </div> <div class="ulist"> <ul> <li> <p>1.5 kilobyte of RAM per file stored in the server.</p> </li> <li> <p>32 MB of RAM per user.</p> </li> </ul> </div> <div class="paragraph"> <p>Use the fastest processors available with the fastest available bus speed. Faster processors are typically more desirable than a greater number of cores and provide better performance since quick bursts of computational speed are more important to Perforce’s performance than the number of processors. Have a minimum of two processors so that the offline checkpoint and back up processes do not interfere with your Perforce server. There are log analysis options to diagnose underperforming servers and improve things (contact support/consulting for details).</p> </div> </div> <div class="sect3"> <h4 id="_directory_structure_configuration_script_for_linuxunix">A.1.2. Directory Structure Configuration Script for Linux/Unix</h4> <div class="paragraph"> <p>This script describes the steps performed by the mkdirs.sh script on Linux/Unix platforms. Please review this appendix carefully before running these steps manually. Assuming the three-volume configuration described in the Volume Layout and Hardware section are used, the following directories are created. The following examples are illustrated with "1" as the server instance number.</p> </div> <table class="tableblock frame-all grid-all stretch"> <colgroup> <col style="width: 50%;"> <col style="width: 50%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-top"><em>Directory</em></th> <th class="tableblock halign-left valign-top"><em>Remarks</em></th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/p4</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Must be under root (<code>/</code>) on the OS volume</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/hxdepots/p4/1/bin</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Files in here are generated by the mkdirs.sh script.</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/hxdepots/p4/1/depots</code></p></td> <td class="tableblock halign-left valign-top"></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/hxdepots/p4/1/tmp</code></p></td> <td class="tableblock halign-left valign-top"></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/hxdepots/p4/common/config</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Contains p4_<instance>.vars file, e.g. <code>p4_1.vars</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/hxdepots/p4/common/bin</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Files from <code>$SDP/Server/Unix/p4/common/bin</code>.</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/hxdepots/p4/common/etc</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Contains <code>init.d</code> and <code>cron.d</code>.</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/hxlogs/p4/1/logs/old</code></p></td> <td class="tableblock halign-left valign-top"></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/hxmetadata2/p4/1/db2</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Contains offline copy of main server databases (linked by <code>/p4/1/offline_db</code>.</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/hxmetadata1/p4/1/db1/save</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Used only during running of <code>refresh_P4ROOT_from_offline_db.sh</code> for extra redundancy.</p></td> </tr> </tbody> </table> <div class="paragraph"> <p>Next, <code>mkdirs.sh</code> creates the following symlinks in the <code>/hxdepots/p4/1</code> directory:</p> </div> <table class="tableblock frame-all grid-all stretch"> <colgroup> <col style="width: 33.3333%;"> <col style="width: 33.3333%;"> <col style="width: 33.3334%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-top"><strong><em>Link source</em></strong></th> <th class="tableblock halign-left valign-top"><strong><em>Link target</em></strong></th> <th class="tableblock halign-left valign-top"><strong><em>Command</em></strong></th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/hxmetadata1/p4/1/db1</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/p4/1/root</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>ln -s /hxmetadata1/p4/1/root</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/hxmetadata2/p4/1/db2</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/p4/1/offline_db</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>ln -s /hxmetadata1/p4/1/offline_db</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/hxlogs/p4/1/logs</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/p4/1/logs</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>ln -s /hxlogs/p4/1/logs</code></p></td> </tr> </tbody> </table> <div class="paragraph"> <p>Then these symlinks are created in the /p4 directory:</p> </div> <table class="tableblock frame-all grid-all stretch"> <colgroup> <col style="width: 33.3333%;"> <col style="width: 33.3333%;"> <col style="width: 33.3334%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-top"><strong><em>Link source</em></strong></th> <th class="tableblock halign-left valign-top"><strong><em>Link target</em></strong></th> <th class="tableblock halign-left valign-top"><strong><em>Command</em></strong></th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/hxdepots/p4/1</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/p4/1</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>ln -s /hxdepots/p4/1 /p4/1</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/hxdepots/p4/common</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/p4/common</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>ln -s /hxdepots/p4/common /p4/common</code></p></td> </tr> </tbody> </table> <div class="paragraph"> <p>Next, <code>mkdirs.sh</code> renames the Perforce binaries to include version and build number, and then creates appropriate symlinks.</p> </div> </div> <div class="sect3"> <h4 id="_p4d_versions_and_links">A.1.3. P4D versions and links</h4> <div class="paragraph"> <p>The versioned binary links in <code>/p4/common/bin</code> are as below.</p> </div> <div class="paragraph"> <p>For the example of <instance> <code>1</code> we have:</p> </div> <div class="literalblock"> <div class="content"> <pre>ls -l /p4/1/bin p4d_1 -> /p4/common/bin/p4d_1_bin</pre> </div> </div> <div class="paragraph"> <p>The structure is shown in this example, illustrating values for two instances, with instance #1 using p4d release 2018.1 and instance #2 using release 2018.2.</p> </div> <div class="paragraph"> <p>In /p4/1/bin:</p> </div> <div class="literalblock"> <div class="content"> <pre>p4_1 -> /p4/common/bin/p4_1_bin p4d_1 -> /p4/common/bin/p4d_1_bin</pre> </div> </div> <div class="paragraph"> <p>In /p4/2/bin:</p> </div> <div class="literalblock"> <div class="content"> <pre>p4_2 -> /p4/common/bin/p4_2 p4d_2 -> /p4/common/bin/p4d_2</pre> </div> </div> <div class="paragraph"> <p>In <code>/p4/common/bin</code>:</p> </div> <div class="literalblock"> <div class="content"> <pre>p4_1_bin -> p4_2018.1_bin p4_2018.1_bin -> p4_2018.1.685046 p4_2018.1.685046</pre> </div> </div> <div class="literalblock"> <div class="content"> <pre>p4_2_bin -> p4_2018.2_bin p4_2018.2_bin -> p4_2018.2.700949 p4_2018.2.700949</pre> </div> </div> <div class="literalblock"> <div class="content"> <pre>p4d_1_bin -> p4d_2018.1_bin p4d_2018.1_bin -> p4d_2018.1.685046 p4d_2018.1.685046</pre> </div> </div> <div class="literalblock"> <div class="content"> <pre>p4d_2_bin -> p4d_2018.2_bin p4d_2018.2_bin -> p4d_2018.2.700949 p4d_2018.2.700949</pre> </div> </div> <div class="paragraph"> <p>The naming of the last comes from:</p> </div> <div class="literalblock"> <div class="content"> <pre>./p4d_2018.2.700949 -V : Rev. P4D/LINUX26X86_64/2018.2/700949 (2019/07/31). :</pre> </div> </div> <div class="paragraph"> <p>So we see the build number <code>p4d_2018.2.700949</code> being included in the name of the p4d executable.</p> </div> <div class="admonitionblock tip"> <table> <tr> <td class="icon"> <i class="fa icon-tip" title="Tip"></i> </td> <td class="content"> Although this link structure may appear quite complex, it is easy to understand, and it allows different instances on the same server host to be running with different patch levels, or indeed different releases. And you can upgrade those instances independently of each other which can be very useful. </td> </tr> </table> </div> </div> <div class="sect3"> <h4 id="_case_insensitive_p4d_on_unix">A.1.4. Case Insensitive P4D on Unix</h4> <div class="paragraph"> <p>By default <code>p4d</code> is case sensitive on Unix for filenames and directory names etc.</p> </div> <div class="paragraph"> <p>It is possible and quite common to run your server in case insensitive mode. This is often done when Windows is the main operating system in use on the client host machines.</p> </div> <div class="admonitionblock important"> <table> <tr> <td class="icon"> <i class="fa icon-important" title="Important"></i> </td> <td class="content"> In "case insensitive" mode, that means that you should ALWAYS execute <code>p4d</code> with the flag <code>-C1</code> (or you risk possible table corruption in some circumstances). </td> </tr> </table> </div> <div class="paragraph"> <p>The SDP achieves this by executing a simple Bash script:</p> </div> <div class="literalblock"> <div class="content"> <pre>#!/bin/bash P4D=/p4/common/bin/p4d_${SDP_INSTANCE}_bin # shellcheck disable=SC2016 exec $P4D -C1 "$@"</pre> </div> </div> <div class="paragraph"> <p>So the above will ensure that <code>/p4/common/bin/p4d_1_bin</code> (for instance <code>1</code>) is executed with the <code>-C1</code> flag.</p> </div> <div class="paragraph"> <p>As noted above, for case sensitive servers, <code>p4d_1</code> is normally just a link:</p> </div> <div class="literalblock"> <div class="content"> <pre>/p4/1/bin/p4d_1 -> /p4/common/bin/p4d_1_bin</pre> </div> </div> </div> </div> </div> </div> <div class="sect1"> <h2 id="_frequently_asked_questionstroubleshooting">Appendix B: Frequently Asked Questions/Troubleshooting</h2> <div class="sectionbody"> <div class="paragraph"> <p>This appendix lists common questions and problems encountered by SDP users. Do not hesitate to contact <a href="mailto:consulting@perforce.com">consulting@perforce.com</a> if additional assistance is required.</p> </div> <div class="sect2"> <h3 id="_journal_out_of_sequence">B.1. Journal out of sequence</h3> <div class="paragraph"> <p>This error is encountered when the offline and live databases are no longer in sync, and will cause the offline checkpoint process to fail. Because the scripts will replay all outstanding journals, this error is much less likely to occur. This error can be fixed by running the <a href="#_live_checkpoint_sh">Section 7.2.6, “live_checkpoint.sh”</a> script. Alternatively, if you know that the checkpoints created from previous runs of <a href="#_daily_checkpoint_sh">Section 7.2.4, “daily_checkpoint.sh”</a> are correct, then restore the <code>offline_db</code> from the last known good checkpoint.</p> </div> </div> <div class="sect2"> <h3 id="_unexpected_end_of_file_in_replica_daily_sync">B.2. Unexpected end of file in replica daily sync</h3> <div class="paragraph"> <p>Check the start time and duration of the <a href="#_daily_checkpoint_sh">Section 7.2.4, “daily_checkpoint.sh”</a> cron job on the master. If this overlaps with the start time of the <a href="#_sync_replica_sh">Section 7.4.27, “sync_replica.sh”</a> cron job on a replica, a truncated checkpoint may be rsync’d to the replica and replaying this will result in an error.</p> </div> <div class="paragraph"> <p>Adjust the replica’s cronjob to start later to resolve this.</p> </div> <div class="paragraph"> <p>Default cron job times, as installed by the SDP are initial estimates, and should be adjusted to suit your production environment.</p> </div> </div> </div> </div> </div> <div id="footer"> <div id="footer-text"> Version v2020.1<br> Last updated 2020-09-15 11:53:42 +0100 </div> </div> </body> </html>
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#125 | 30938 | Robert Cowham |
Minor clarifications for getting started using install_sdp.sh script Updated some links to new Helix Core doc locations. |
||
#124 | 30937 | Robert Cowham |
Update p4review2.py to work with Python3 Add basic test harness. Delete p4review.py which is Python2 and update docs. |
||
#123 | 30926 | C. Thomas Tyler | Updated version for release. | ||
#122 | 30913 | C. Thomas Tyler | Regnerated docs for release. | ||
#121 | 30837 | C. Thomas Tyler | Added ref to new storage doc. | ||
#120 | 30835 | C. Thomas Tyler |
Adapted Server Spec Naming Standard section detailing the ServerID of the commit server to the defacto standard already used in HRA. Changed from: {commit|master}[.<SDPInstance>[.<OrgName>]] to: {commit|master}[.<OrgName>[.<SDPInstance>]] Various typo fixes and minor changes in SDP Guide. Updated consulting email address (now consulting-helix-core@perforce.com) in various files. |
||
#119 | 30782 | C. Thomas Tyler |
Added new install_sdp.sh script and supporting documentation. The new install_sdp.sh makes SDP independent of the separate Helix Installer software (the reset_sdp.sh script). The new script greatly improves the installation experience for new server machines. It is ground up rewrite of the reset_sdp.sh script. The new script preserves the desired behaviors of the original Helix Installer script, but is focused on the use case of a fresh install on a new server machine. With this focus, the scripts does not have any "reset" logic, making it completely safe. Added various files and functionalityfrom Helix Installer into SDP. * Added firewalld templates to SDP, and added ufw support. * Improved sudoers generation. * Added bash shell templates. This script also installs in the coming SDP Package structure. New installs use a modified SDP structure that makes it so the /p4/sdp and /p4/common now point to folders on the local OS volume rather than the /hxepots volume. The /hxdepots volume, which is often NFS mounted, is still used for depots and checkpoints, and for backups. The new structure uses a new /opt/perforce/helix-sdp structure under which /p4/sdp and /p4/common point. This structure also contains the expaneded SDP tarball, downloads, helix_binaries, etc. This change represents the first of 3-phase rollout of the new package structure. In this first phase, the "silent beta" phase, the new structure is used for new installations only. This phase requires no changes to released SDP scripts except for mkdirs.sh, and even that script remains backward-compatible with the old structure if used independently of install_sdp.sh. If used with install_sdp.sh, the new structure is used. In the second phase (targeted for SPD 2024.2 release), the sdp_upgrade.sh script will convert existing installations to the new structure. In the third phase (targeted for SDP 2025.x), this script will be incorporated into OS pacakge installations for the helix-sdp package. Perforce internal wikis have more detail on this change. #review-30783 |
||
#118 | 30661 | Robert Cowham | Exapand description for recreate_offline_db.sh | ||
#117 | 30656 | Robert Cowham | Tweak xrefs from failover guide and sdp guide. | ||
#116 | 30608 | C. Thomas Tyler |
Fixed doc typo in triggers table call; trigger type should be 'change-submit', not 'submit-change'. |
||
#115 | 30606 | C. Thomas Tyler |
Updated content related to to perforce-p4python3 package. #review-30607 |
||
#114 | 30531 | C. Thomas Tyler |
Merge down from main to dev with: p4 merge -b perforce_software-sdp-dev |
||
#113 | 30516 | C. Thomas Tyler | Doc corrections and clarifications. | ||
#112 | 30440 | Robert Cowham | Add a couple of emphases... | ||
#111 | 30385 | C. Thomas Tyler | Regnerated docs for release. | ||
#110 | 30367 | C. Thomas Tyler |
Updated Server Spec Naming Standard to account for allowing 'commit' to be used as a synonym for 'master', and also allowing for appending an optional '<OrgName>'. |
||
#109 | 30294 | C. Thomas Tyler | Updated docs for release. | ||
#108 | 30285 | C. Thomas Tyler |
Updated SDP Guide for Unix to include raw perforce_suoders.t file for better accuracy and easier update. Added a copy of perforce_sudoers.t from Helix Installer. For immediate purposes, this is to allow this file to be included in SDP documentation. However, this change is also part of a larger goal to move extensive Helix Installer functionality into the SDP. |
||
#107 | 30205 | C. Thomas Tyler | Refactored Terminology so we can reference indiviual terms with direct URLs. | ||
#106 | 30168 | Mark Zinthefer | updating the Unix docs | ||
#105 | 30040 | C. Thomas Tyler | Regenerated docs. | ||
#104 | 30031 | C. Thomas Tyler | Added doc for ccheck.sh, keep_offline_db_current.sh. | ||
#103 | 30008 | C. Thomas Tyler |
Doc change and Non-functional updates to CheckCaseTrigger.py: * Bumped version number for recent changes. * Fixed doc inconsistencies. Fixes: SDP-1035 #review-30009 |
||
#102 | 30000 | C. Thomas Tyler |
Refined Release Notes and top-level README.md file in preparation for coming 2023.2 release. Adjusted Makefile in doc directory to also generate top-level README.html from top-level README.md file so that the HTML file is reliably updated in the SDP release process. Updated :revnumber: and :revdate: docs in AsciiDoc files to indicate that the are still current. Avoiding regen of ReleaseNotes.pdf binary file since that will need at least one more update before shipping SDP 2023.2. |
||
#101 | 29953 | C. Thomas Tyler | Regeneratd docs. | ||
#100 | 29912 | Robert Cowham | Remove link to Helix Installer until we refactor that to avoid support errors. | ||
#99 | 29890 | C. Thomas Tyler | Regenerated docs. | ||
#98 | 29844 | C. Thomas Tyler |
Added sdp_health_check to SDP package. Updated docs in Guide and Release Notes to reflect this change. Added more docs for this in the SDP Guide. #review-29845 @vkanczes |
||
#97 | 29826 | C. Thomas Tyler | Regenerated HTML. | ||
#96 | 29824 | C. Thomas Tyler |
Added comment that P4SERVICEPASS is not used; it remains in place for backward compatibility. Added FAQ: How do I change super user password? Added FAQ: Can I remove the perforce user? Added FAQ: Can I clone a VM to create a standby replica? #review-29825 |
||
#95 | 29727 | Robert Cowham | Note the need for an extra p4 trust statement for $HOSTNAME | ||
#94 | 29719 | Robert Cowham |
Fix journal numbering example. Add section to make replication errors visible. |
||
#93 | 29715 | C. Thomas Tyler |
Doc correction. The sample command correctly indicates that `/home/perforce` should be the home directory, but the text still says should be `/p4`, the legacy location. Also added a note advising against user of automounted home dirs. #review-29716 |
||
#92 | 29700 | C. Thomas Tyler |
Updated Version to release SDP 2023.1.29699. Re-generated docs. |
||
#91 | 29693 | C. Thomas Tyler |
Adjusted /hxserverlocks recommendations: * Changed filesystem name from 'tmpfs' to 'HxServerLocks' in /etc/fstab. * Changed mount permissions from '0755' to '0700' to prevent data leaks. * Changed mounted filesystem size recommendations. * Updated info about size of files being 17 or 0 bytes depending on p4d version. * Indicated change should be done in a maintenance window (as /etc/fstab is modified). Also updated limited sudoers to include entries for running setcap and getcap. #review-29694 @robert_cowham |
||
#90 | 29622 | C. Thomas Tyler |
Updated Version to release SDP 2023.1.29621. Re-generated docs. |
||
#89 | 29611 | C. Thomas Tyler |
Updated Version to release SDP 2023.1.29610. Re-generated docs. |
||
#88 | 29483 | Robert Cowham | Clarify case-insensitive servers | ||
#87 | 29475 | Robert Cowham | For SELinux note the yum package to install for basics | ||
#86 | 29442 | C. Thomas Tyler |
Updated Version to release SDP 2022.2.29441. Re-generated docs. |
||
#85 | 29400 | C. Thomas Tyler |
Updated Version to release SDP 2022.2.29399. Re-generated docs. |
||
#84 | 29311 | C. Thomas Tyler |
Per Thomas Albert, adjusted title on doc page: From: Perforce Helix Server Deployment Package (for UNIX/Linux) To: Perforce Helix Core Server Deployment Package (for UNIX/Linux) #review-29312 @thomas_albert |
||
#83 | 29251 | C. Thomas Tyler |
Updated Version to release SDP 2022.2.29250. Re-generated docs. |
||
#82 | 29204 | C. Thomas Tyler |
Updated Version to release SDP 2022.1.29203. Re-generated docs. |
||
#81 | 29142 | C. Thomas Tyler |
Updated Version to release SDP 2022.1.29141. Re-generated docs. |
||
#80 | 29137 | C. Thomas Tyler | Added docs for proxy_rotate.sh, and updated docs for broker_rotate.sh. | ||
#79 | 29096 | Robert Cowham | Add a section on installing Swarm triggers | ||
#78 | 29055 | Robert Cowham | Update troubleshooting to check ckp_running.txt semaphore | ||
#77 | 29044 | Robert Cowham | Update to include troubleshooting 'p4 pull -ls' errors | ||
#76 | 29002 | C. Thomas Tyler |
Doc correction; tip refers to 'wget' in a sample command that uses curl instead. |
||
#75 | 28988 | C. Thomas Tyler |
Updated Version to release SDP 2022.1.28987. Re-generated docs. |
||
#74 | 28986 | C. Thomas Tyler |
Clarified text related to mandatory vs. nomandatory standby replicas. |
||
#73 | 28980 | Robert Cowham | Note how to configure Swarm to use postfix | ||
#72 | 28926 | Robert Cowham | Added check for Swarm JIRA project access. | ||
#71 | 28840 | C. Thomas Tyler |
Updated Version to release SDP 2022.1.28839. Re-generated docs. |
||
#70 | 28767 | C. Thomas Tyler |
SDP Guide Doc Updates: * Fixed typos. * Enhanced mandatory/nomandatory description. * Added detail to instructions on using the `perforce-p4python` packcage, and change reference from Swarm docs to the more general Perforce Packages page. * Refactored FAQ, Troubleshooting Guide, and Sample Procedures appendices for greater clarity. * Added Appendix on Brokers in Stack Topology #review-28768 |
||
#69 | 28686 | Robert Cowham | Clarify FAQ for replication errors | ||
#68 | 28667 | Robert Cowham |
Add a note re monitoring. Add some FAQ appendix questions. |
||
#67 | 28650 | C. Thomas Tyler |
Updated Version to release SDP 2021.2.28649. Re-generated docs. |
||
#66 | 28618 | C. Thomas Tyler | Fixed missing command re: .ssh directory generation. | ||
#65 | 28606 | C. Thomas Tyler |
Added SDP Health Checks appendix to UNIX/Linux SDP Guide. Also removed some references to '-k' (insecure) in curl statements. #review-28607 @d_benedict |
||
#64 | 28604 | Robert Cowham | Added notes for Python/P4Python and CheckCaseTrigger installation | ||
#63 | 28503 | Robert Cowham | Add SELinux tip | ||
#62 | 28496 | Robert Cowham | Fix typo in journalctl | ||
#61 | 28493 | Robert Cowham |
Added notes to get systemd SDP scripts working under SELinux Thanks to Rich Alloway! |
||
#60 | 28411 | C. Thomas Tyler |
Updated Version to release SDP 2021.2.28410. Re-generated docs. |
||
#59 | 28351 | Robert Cowham | Tweaked sdp upgrades docs. | ||
#58 | 28261 | C. Thomas Tyler | Fixed on-character doc typo (curk -> curl). | ||
#57 | 28257 | C. Thomas Tyler |
Updated Version to release SDP 2021.1.28253. Re-generated docs. |
||
#56 | 28246 | C. Thomas Tyler |
Enahnced the 'Upgrading the SDP' section of the SDP Guide: * Added sample command to deal with possibly existing tarball. * Added tips to enable less technical users to get past basic snags. * Added detail on how to find your /hxdepots directory if not default. |
||
#55 | 28239 | C. Thomas Tyler |
Updated Version to release SDP 2021.1.28238. Re-generated docs. |
||
#54 | 28230 | C. Thomas Tyler | Minor doc corrections. | ||
#53 | 28225 | C. Thomas Tyler | Enhanced info on upgrading the SDP. | ||
#52 | 28180 | C. Thomas Tyler |
Fixed oversight in documentation, describing how to check the SDP Version file. |
||
#51 | 28160 | C. Thomas Tyler | Regenerated HTML (no PDF) for easy review. | ||
#50 | 28154 | C. Thomas Tyler |
Added new Sample Procedures section. Added Sample Procedure: Reseeding an Edge Server Corrected teriminology re: 'instance' and 'process' and 'server' to be inline with other documentation and common usage. Other minor fixes. #review-28155 |
||
#49 | 28104 | C. Thomas Tyler | Fixed typo. | ||
#48 | 28102 | C. Thomas Tyler |
Clarified "breathing" comment (as in "breathing room") with more clear and more translatable language. #review-28103 @thomas_albert |
||
#47 | 28100 | C. Thomas Tyler |
Updated SDP Guide for UNIX/Linux: * Filled in missing information re: new upgrades. * Expanded on definition of vague "Exceptionally large" term. Generating HTML for easy review; holding off on PDF as it will be generated during the release. #review-28101 @roadkills_r_us |
||
#46 | 28071 | Robert Cowham | Clarify some notes re setting up Gmail | ||
#45 | 27978 | Robert Cowham |
Clarifications and warnings around load_checkpoint.sh Mention recreate_offline_db.sh a little more prominently Recommend installing postfix for mail. |
||
#44 | 27920 | C. Thomas Tyler |
Updated Version to release SDP 2020.1.27919. Re-generated docs. |
||
#43 | 27900 | C. Thomas Tyler |
Updated Version to release SDP 2020.1.27899. Re-generated docs. |
||
#42 | 27890 | C. Thomas Tyler |
Updated Release Notes and SDP Guide to clarify SDP r20.1 supports Helix Core binaries up to r21.1, in advance of the coming SDP r21.1 release that will make it more obvious. In get_helix_binaries.sh: * Changed default Helix Core binary version to r21.1. * Changed examples of getting a different version to reference r20.2. #review-27891 @amo |
||
#41 | 27821 | C. Thomas Tyler |
Updated Version to release SDP 2020.1.27820. Re-generated docs. |
||
#40 | 27764 | C. Thomas Tyler |
Updated Version to release SDP 2020.1.27763. Re-generated docs. |
||
#39 | 27760 | C. Thomas Tyler |
Updated Version to release SDP 2020.1.27759. Re-generated docs. |
||
#38 | 27725 | C. Thomas Tyler | Re-generated HTML and PDF from adoc files. | ||
#37 | 27722 | C. Thomas Tyler |
Refinements to @27712: * Resolved one out-of-date file (verify_sdp.sh). * Added missing adoc file for which HTML file had a change (WorkflowEnforcementTriggers.adoc). * Updated revdate/revnumber in *.adoc files. * Additional content updates in Server/Unix/p4/common/etc/cron.d/ReadMe.md. * Bumped version numbers on scripts with Version= def'n. * Generated HTML, PDF, and doc/gen files: - Most HTML and all PDF are generated using Makefiles that call an AsciiDoc utility. - HTML for Perl scripts is generated with pod2html. - doc/gen/*.man.txt files are generated with .../tools/gen_script_man_pages.sh. #review-27712 |
||
#36 | 27710 | Robert Cowham | Another tweak to tmpfs settings | ||
#35 | 27709 | Robert Cowham |
Note check for serverlocks. Fix typo in path in failover. |
||
#34 | 27536 | C. Thomas Tyler |
Legacy Upgrade Guide doc updates: * Added 'Put New SDP in Place' section. * Added 'Set SDP Counters' section to set SDP_VERSION and SDP_DATE counters. * Covered updating depot spec Map fields. * Covered adding server.id files. * Added missing content on putting new SDP directory in place. SDP_Guide.Unix doc updates: * Added Legacy Upgrade Scripts section w/clear_depot_Map_fields.sh. Updated Makefile with new doc build dependencies. Regenerated docs. |
||
#33 | 27526 | C. Thomas Tyler |
Updated Version to release SDP 2020.1.27524. Re-generated docs. |
||
#32 | 27505 | C. Thomas Tyler |
Enhanced doc for Systemd/SysV services management and configuration docs, separating basic configuration for start/stop/status from enabling for start on boot (with Systemd/SysV variations for each). Added doc coverage for using systemd to enable multiple broker configs. Added doc coverage for applying limited sudo. Spell check. |
||
#31 | 27462 | C. Thomas Tyler |
Updated Version to release SDP 2020.1.27457. Re-generated docs. |
||
#30 | 27414 | C. Thomas Tyler | Updated SDP Guide. | ||
#29 | 27406 | C. Thomas Tyler | Updated Version to release SDP 2020.1.27403. | ||
#28 | 27398 | C. Thomas Tyler | Refined Makefile for generating docs and regenerated docs. | ||
#27 | 27351 | C. Thomas Tyler | Updated AsciiDoc-generated files. | ||
#26 | 27322 | C. Thomas Tyler | Updated AsciiDoc-generated files. | ||
#25 | 27253 | C. Thomas Tyler | Updated generated docs. | ||
#24 | 27213 | C. Thomas Tyler | Regenerated docs. | ||
#23 | 27156 | C. Thomas Tyler |
Consolidated SDP Standards into the SDP Guide for UNIX/Linux. Added references to those sections in the Windows SDP Guide. Normalized doc titles. Various other doc update. |
||
#22 | 27096 | C. Thomas Tyler |
Refactored SDP Legacy Upgrade content into a separate doc. The SDP Guide will be remain comprehensive and cover how to upgrade the SDP itself forwardm from the current version (2020.1) using the new, p4d-like incremental upgrade mechanism. The content for manual upgrade procedures needed to get older SDP installations to 2020.1 is only useful until sites are on 2020.1. This content is extensive, narrowly focused, and of value only once per installation, and thus the legacy upgrade content is separated into its own document. Regenerated work-in-progress HTML files for easier review. |
||
#21 | 27074 | C. Thomas Tyler | Regenerated SDP Guide docs from adoc. | ||
#20 | 27058 | Robert Cowham |
Added direct links to the various scripts where they are explained. Tweak some wording in SDP upgrade section |
||
#19 | 27055 | C. Thomas Tyler |
Pulled the SDP Upgrade Guide for Linux into the main SDP Guide, and deleted the separate upgrade doc. Also other minor refinements. Pulled in updated mkrep.sh v2.5.0 docs. This version is still in progress. Search for EDITME to find areas requiring addtional content. |
||
#18 | 27041 | Robert Cowham |
Windows Guide directly includes chunks of the Unix guide for replication etc, with a little ifdef to avoid Unix only comments. Fix Makefile and add missing generated man page. |
||
#17 | 27033 | C. Thomas Tyler | Work in progress updates to SDP_Guilde.Unix. | ||
#16 | 27021 | C. Thomas Tyler |
Re-ordered so `systemd` info comes first (as it is more likely to be relevant), and older SysV docs deferred. Various other tweaks. |
||
#15 | 27014 | C. Thomas Tyler | Regenerated AsciiDoc output. | ||
#14 | 26992 | Robert Cowham | Document SiteTags.cfg file | ||
#13 | 26851 | Robert Cowham |
Fix typo in tmpfs /etc/fstab entry which stopped it working in the doc. Mention in pre-requisites for failover and failover guide the need to review OS Config for your failover server. Document Ubuntu 2020.04 LTS and CentOS/RHEL 8 support. Note performance has been observed to be better with CentOS. Document pull.sh and submit.sh in main SDP guide (remove from Unsupported doc). Update comments in triggers to reflect that they are reference implementations, not just examples. No code change. |
||
#12 | 26780 | Robert Cowham | Complete rename of P4DNSNAME -> P4MASTERHOST | ||
#11 | 26755 | Robert Cowham | Include p4verify.sh man page in SDP Guide automatically for usage section. | ||
#10 | 26748 | Robert Cowham |
Add recommended performance tweaks: - THP off - server.locks directory into RAM |
||
#9 | 26747 | Robert Cowham |
Update with some checklists for failover to ensure valid. Update to v2020.1 Add Usage sections where missing to Unix guide Refactor the content in Unix guide to avoid repetition and make things read more sensibly. |
||
#8 | 26727 | Robert Cowham |
Add section on server host naming conventions Clarify HA and DR, and update links across docs Fix doc structure for Appendix numbering |
||
#7 | 26661 | Robert Cowham |
Tidying up cross references. Added missing sync_replica.sh docs. |
||
#6 | 26654 | Robert Cowham |
First draft of new Failover Guide using "p4 failover" Linked from SDP Unix Guide |
||
#5 | 26649 | Robert Cowham |
More SDP Doc tidy up. Removed some command summary files. |
||
#4 | 26644 | Robert Cowham |
SDP Doc Update to address jobs. Mainly documents scripts which lacked any mention. |
||
#3 | 26637 | Robert Cowham |
Include script help within doc Requires a couple of tags in the scripts themselves. |
||
#2 | 26631 | Robert Cowham | New AsciiDoc version of Windows SDP guide | ||
#1 | 26629 | Robert Cowham |
Fixed Makefile to generate HTML Check in theme Some notes in README Remove the .docx! |