文章
Nicky Zhu · 九月 27, 2021
html {overflow-x: initial !important;}:root { --bg-color: #ffffff; --text-color: #333333; --select-text-bg-color: #B5D6FC; --select-text-font-color: auto; --monospace: "Lucida Console",Consolas,"Courier",monospace; --title-bar-height: 20px; }
.mac-os-11 { --title-bar-height: 28px; }
html { font-size: 14px; background-color: var(--bg-color); color: var(--text-color); font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; }
body { margin: 0px; padding: 0px; height: auto; inset: 0px; font-size: 1rem; line-height: 1.42857143; overflow-x: hidden; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; tab-size: 4; background-position: inherit; background-repeat: inherit; }
iframe { margin: auto; }
a.url { word-break: break-all; }
a:active, a:hover { outline: 0px; }
.in-text-selection, ::selection { text-shadow: none; background: var(--select-text-bg-color); color: var(--select-text-font-color); }
#write { margin: 0px auto; height: auto; width: inherit; word-break: normal; word-wrap: break-word; position: relative; white-space: normal; overflow-x: visible; padding-top: 36px; }
#write.first-line-indent p { text-indent: 2em; }
#write.first-line-indent li p, #write.first-line-indent p * { text-indent: 0px; }
#write.first-line-indent li { margin-left: 2em; }
.for-image #write { padding-left: 8px; padding-right: 8px; }
body.typora-export { padding-left: 30px; padding-right: 30px; }
.typora-export .footnote-line, .typora-export li, .typora-export p { white-space: pre-wrap; }
.typora-export .task-list-item input { pointer-events: none; }
@media screen and (max-width: 500px) {
body.typora-export { padding-left: 0px; padding-right: 0px; }
#write { padding-left: 20px; padding-right: 20px; }
.CodeMirror-sizer { margin-left: 0px !important; }
.CodeMirror-gutters { display: none !important; }
}
#write li > figure:last-child { margin-bottom: 0.5rem; }
#write ol, #write ul { position: relative; }
img { max-width: 100%; vertical-align: middle; image-orientation: from-image; }
button, input, select, textarea { color: inherit; font-family: inherit; font-size: inherit; font-style: inherit; font-variant-caps: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; }
input[type="checkbox"], input[type="radio"] { line-height: normal; padding: 0px; }
*, ::after, ::before { box-sizing: border-box; }
#write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p, #write pre { width: inherit; }
#write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p { position: relative; }
p { line-height: inherit; }
h1, h2, h3, h4, h5, h6 { break-after: avoid-page; break-inside: avoid; orphans: 4; }
p { orphans: 4; }
h1 { font-size: 2rem; }
h2 { font-size: 1.8rem; }
h3 { font-size: 1.6rem; }
h4 { font-size: 1.4rem; }
h5 { font-size: 1.2rem; }
h6 { font-size: 1rem; }
.md-math-block, .md-rawblock, h1, h2, h3, h4, h5, h6, p { margin-top: 1rem; margin-bottom: 1rem; }
.hidden { display: none; }
.md-blockmeta { color: rgb(204, 204, 204); font-weight: 700; font-style: italic; }
a { cursor: pointer; }
sup.md-footnote { padding: 2px 4px; background-color: rgba(238, 238, 238, 0.7); color: rgb(85, 85, 85); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; cursor: pointer; }
sup.md-footnote a, sup.md-footnote a:hover { color: inherit; text-transform: inherit; text-decoration: inherit; }
#write input[type="checkbox"] { cursor: pointer; width: inherit; height: inherit; }
figure { overflow-x: auto; margin: 1.2em 0px; max-width: calc(100% + 16px); padding: 0px; }
figure > table { margin: 0px; }
tr { break-inside: avoid; break-after: auto; }
thead { display: table-header-group; }
table { border-collapse: collapse; border-spacing: 0px; width: 100%; overflow: auto; break-inside: auto; text-align: left; }
table.md-table td { min-width: 32px; }
.CodeMirror-gutters { border-right-width: 0px; background-color: inherit; }
.CodeMirror-linenumber { }
.CodeMirror { text-align: left; }
.CodeMirror-placeholder { opacity: 0.3; }
.CodeMirror pre { padding: 0px 4px; }
.CodeMirror-lines { padding: 0px; }
div.hr:focus { cursor: none; }
#write pre { white-space: pre-wrap; }
#write.fences-no-line-wrapping pre { white-space: pre; }
#write pre.ty-contain-cm { white-space: normal; }
.CodeMirror-gutters { margin-right: 4px; }
.md-fences { font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; overflow: visible; white-space: pre; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; position: relative !important; background-position: inherit; background-repeat: inherit; }
.md-fences-adv-panel { width: 100%; margin-top: 10px; text-align: center; padding-top: 0px; padding-bottom: 8px; overflow-x: auto; }
#write .md-fences.mock-cm { white-space: pre-wrap; }
.md-fences.md-fences-with-lineno { padding-left: 0px; }
#write.fences-no-line-wrapping .md-fences.mock-cm { white-space: pre; overflow-x: auto; }
.md-fences.mock-cm.md-fences-with-lineno { padding-left: 8px; }
.CodeMirror-line, twitterwidget { break-inside: avoid; }
.footnotes { opacity: 0.8; font-size: 0.9rem; margin-top: 1em; margin-bottom: 1em; }
.footnotes + .footnotes { margin-top: 0px; }
.md-reset { margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: top; text-decoration: none; text-shadow: none; float: none; position: static; width: auto; height: auto; white-space: nowrap; cursor: inherit; line-height: normal; font-weight: 400; text-align: left; box-sizing: content-box; direction: ltr; background-position: 0px 0px; }
li div { padding-top: 0px; }
blockquote { margin: 1rem 0px; }
li .mathjax-block, li p { margin: 0.5rem 0px; }
li blockquote { margin: 1rem 0px; }
li { margin: 0px; position: relative; }
blockquote > :last-child { margin-bottom: 0px; }
blockquote > :first-child, li > :first-child { margin-top: 0px; }
.footnotes-area { color: rgb(136, 136, 136); margin-top: 0.714rem; padding-bottom: 0.143rem; white-space: normal; }
#write .footnote-line { white-space: pre-wrap; }
@media print {
body, html { border: 1px solid transparent; height: 99%; break-after: avoid; break-before: avoid; font-variant-ligatures: no-common-ligatures; }
#write { margin-top: 0px; padding-top: 0px; border-color: transparent !important; }
.typora-export * { -webkit-print-color-adjust: exact; }
.typora-export #write { break-after: avoid; }
.typora-export #write::after { height: 0px; }
.is-mac table { break-inside: avoid; }
.typora-export-show-outline .typora-export-sidebar { display: none; }
}
.footnote-line { margin-top: 0.714em; font-size: 0.7em; }
a img, img a { cursor: pointer; }
pre.md-meta-block { font-size: 0.8rem; min-height: 0.8rem; white-space: pre-wrap; background-color: rgb(204, 204, 204); display: block; overflow-x: hidden; }
p > .md-image:only-child:not(.md-img-error) img, p > img:only-child { display: block; margin: auto; }
#write.first-line-indent p > .md-image:only-child:not(.md-img-error) img { left: -2em; position: relative; }
p > .md-image:only-child { display: inline-block; width: 100%; }
#write .MathJax_Display { margin: 0.8em 0px 0px; }
.md-math-block { width: 100%; }
.md-math-block:not(:empty)::after { display: none; }
.MathJax_ref { fill: currentcolor; }
[contenteditable="true"]:active, [contenteditable="true"]:focus, [contenteditable="false"]:active, [contenteditable="false"]:focus { outline: 0px; box-shadow: none; }
.md-task-list-item { position: relative; list-style-type: none; }
.task-list-item.md-task-list-item { padding-left: 0px; }
.md-task-list-item > input { position: absolute; top: 0px; left: 0px; margin-left: -1.2em; margin-top: calc(1em - 10px); border: none; }
.math { font-size: 1rem; }
.md-toc { min-height: 3.58rem; position: relative; font-size: 0.9rem; border-top-left-radius: 10px; border-top-right-radius: 10px; border-bottom-right-radius: 10px; border-bottom-left-radius: 10px; }
.md-toc-content { position: relative; margin-left: 0px; }
.md-toc-content::after, .md-toc::after { display: none; }
.md-toc-item { display: block; color: rgb(65, 131, 196); }
.md-toc-item a { text-decoration: none; }
.md-toc-inner:hover { text-decoration: underline; }
.md-toc-inner { display: inline-block; cursor: pointer; }
.md-toc-h1 .md-toc-inner { margin-left: 0px; font-weight: 700; }
.md-toc-h2 .md-toc-inner { margin-left: 2em; }
.md-toc-h3 .md-toc-inner { margin-left: 4em; }
.md-toc-h4 .md-toc-inner { margin-left: 6em; }
.md-toc-h5 .md-toc-inner { margin-left: 8em; }
.md-toc-h6 .md-toc-inner { margin-left: 10em; }
@media screen and (max-width: 48em) {
.md-toc-h3 .md-toc-inner { margin-left: 3.5em; }
.md-toc-h4 .md-toc-inner { margin-left: 5em; }
.md-toc-h5 .md-toc-inner { margin-left: 6.5em; }
.md-toc-h6 .md-toc-inner { margin-left: 8em; }
}
a.md-toc-inner { font-size: inherit; font-style: inherit; font-weight: inherit; line-height: inherit; }
.footnote-line a:not(.reversefootnote) { color: inherit; }
.md-attr { display: none; }
.md-fn-count::after { content: "."; }
code, pre, samp, tt { font-family: var(--monospace); }
kbd { margin: 0px 0.1em; padding: 0.1em 0.6em; font-size: 0.8em; color: rgb(36, 39, 41); background-color: rgb(255, 255, 255); border: 1px solid rgb(173, 179, 185); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; box-shadow: rgba(12, 13, 14, 0.2) 0px 1px 0px, rgb(255, 255, 255) 0px 0px 0px 2px inset; white-space: nowrap; vertical-align: middle; }
.md-comment { color: rgb(162, 127, 3); opacity: 0.8; font-family: var(--monospace); }
code { text-align: left; }
a.md-print-anchor { white-space: pre !important; border: none !important; display: inline-block !important; position: absolute !important; width: 1px !important; right: 0px !important; outline: 0px !important; text-shadow: initial !important; background-position: 0px 0px !important; }
.os-windows.monocolor-emoji .md-emoji { font-family: "Segoe UI Symbol", sans-serif; }
.md-diagram-panel > svg { max-width: 100%; }
[lang="flow"] svg, [lang="mermaid"] svg { max-width: 100%; height: auto; }
[lang="mermaid"] .node text { font-size: 1rem; }
table tr th { border-bottom-width: 0px; }
video { max-width: 100%; display: block; margin: 0px auto; }
iframe { max-width: 100%; width: 100%; border: none; }
.highlight td, .highlight tr { border: 0px; }
mark { background-color: rgb(255, 255, 0); color: rgb(0, 0, 0); }
.md-html-inline .md-plain, .md-html-inline strong, mark .md-inline-math, mark strong { color: inherit; }
.md-expand mark .md-meta { opacity: 0.3 !important; }
mark .md-meta { color: rgb(0, 0, 0); }
@media print {
.typora-export h1, .typora-export h2, .typora-export h3, .typora-export h4, .typora-export h5, .typora-export h6 { break-inside: avoid; }
}
.md-diagram-panel .messageText { stroke: none !important; }
.md-diagram-panel .start-state { fill: var(--node-fill); }
.md-diagram-panel .edgeLabel rect { opacity: 1 !important; }
.md-require-zoom-fix { height: auto; margin-top: 16px; margin-bottom: 16px; }
.md-require-zoom-fix foreignObject { font-size: var(--mermaid-font-zoom); }
.md-fences.md-fences-math { font-size: 1em; }
.md-fences-advanced:not(.md-focus) { padding: 0px; white-space: nowrap; border: 0px; }
.md-fences-advanced:not(.md-focus) { background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; background-position: inherit; background-repeat: inherit; }
.typora-export-show-outline .typora-export-content { max-width: 1440px; margin: auto; display: flex; flex-direction: row; }
.typora-export-sidebar { width: 300px; font-size: 0.8rem; margin-top: 80px; margin-right: 18px; }
.typora-export-show-outline #write { --webkit-flex: 2; flex: 2 1 0%; }
.typora-export-sidebar .outline-content { position: fixed; top: 0px; max-height: 100%; overflow: hidden auto; padding-bottom: 30px; padding-top: 60px; width: 300px; }
@media screen and (max-width: 1024px) {
.typora-export-sidebar, .typora-export-sidebar .outline-content { width: 240px; }
}
@media screen and (max-width: 800px) {
.typora-export-sidebar { display: none; }
}
.outline-content li, .outline-content ul { margin-left: 0px; margin-right: 0px; padding-left: 0px; padding-right: 0px; list-style: none; }
.outline-content ul { margin-top: 0px; margin-bottom: 0px; }
.outline-content strong { font-weight: 400; }
.outline-expander { width: 1rem; height: 1.428571429rem; position: relative; display: table-cell; vertical-align: middle; cursor: pointer; padding-left: 4px; }
.outline-expander::before { content: ''; position: relative; font-family: Ionicons; display: inline-block; font-size: 8px; vertical-align: middle; }
.outline-item { padding-top: 3px; padding-bottom: 3px; cursor: pointer; }
.outline-expander:hover::before { content: ''; }
.outline-h1 > .outline-item { padding-left: 0px; }
.outline-h2 > .outline-item { padding-left: 1em; }
.outline-h3 > .outline-item { padding-left: 2em; }
.outline-h4 > .outline-item { padding-left: 3em; }
.outline-h5 > .outline-item { padding-left: 4em; }
.outline-h6 > .outline-item { padding-left: 5em; }
.outline-label { cursor: pointer; display: table-cell; vertical-align: middle; text-decoration: none; color: inherit; }
.outline-label:hover { text-decoration: underline; }
.outline-item:hover { border-color: rgb(245, 245, 245); background-color: var(--item-hover-bg-color); }
.outline-item:hover { margin-left: -28px; margin-right: -28px; border-left-width: 28px; border-left-style: solid; border-left-color: transparent; border-right-width: 28px; border-right-style: solid; border-right-color: transparent; }
.outline-item-single .outline-expander::before, .outline-item-single .outline-expander:hover::before { display: none; }
.outline-item-open > .outline-item > .outline-expander::before { content: ''; }
.outline-children { display: none; }
.info-panel-tab-wrapper { display: none; }
.outline-item-open > .outline-children { display: block; }
.typora-export .outline-item { padding-top: 1px; padding-bottom: 1px; }
.typora-export .outline-item:hover { margin-right: -8px; border-right-width: 8px; border-right-style: solid; border-right-color: transparent; }
.typora-export .outline-expander::before { content: "+"; font-family: inherit; top: -1px; }
.typora-export .outline-expander:hover::before, .typora-export .outline-item-open > .outline-item > .outline-expander::before { content: '−'; }
.typora-export-collapse-outline .outline-children { display: none; }
.typora-export-collapse-outline .outline-item-open > .outline-children, .typora-export-no-collapse-outline .outline-children { display: block; }
.typora-export-no-collapse-outline .outline-expander::before { content: "" !important; }
.typora-export-show-outline .outline-item-active > .outline-item .outline-label { font-weight: 700; }
.md-inline-math-container mjx-container { zoom: 0.95; }
:root {
--side-bar-bg-color: #fafafa;
--control-text-color: #777;
}
@include-when-export url(https://fonts.loli.net/css?family=Open+Sans:400italic,700italic,700,400&subset=latin,latin-ext);
/* open-sans-regular - latin-ext_latin */
/* open-sans-italic - latin-ext_latin */
/* open-sans-700 - latin-ext_latin */
/* open-sans-700italic - latin-ext_latin */
html {
font-size: 16px;
-webkit-font-smoothing: antialiased;
}
body {
font-family: "Open Sans","Clear Sans", "Helvetica Neue", Helvetica, Arial, 'Segoe UI Emoji', sans-serif;
color: rgb(51, 51, 51);
line-height: 1.6;
}
#write {
max-width: 860px;
margin: 0 auto;
padding: 30px;
padding-bottom: 100px;
}
@media only screen and (min-width: 1400px) {
#write {
max-width: 1024px;
}
}
@media only screen and (min-width: 1800px) {
#write {
max-width: 1200px;
}
}
#write > ul:first-child,
#write > ol:first-child{
margin-top: 30px;
}
a {
color: #4183C4;
}
h1,
h2,
h3,
h4,
h5,
h6 {
position: relative;
margin-top: 1rem;
margin-bottom: 1rem;
font-weight: bold;
line-height: 1.4;
cursor: text;
}
h1:hover a.anchor,
h2:hover a.anchor,
h3:hover a.anchor,
h4:hover a.anchor,
h5:hover a.anchor,
h6:hover a.anchor {
text-decoration: none;
}
h1 tt,
h1 code {
font-size: inherit;
}
h2 tt,
h2 code {
font-size: inherit;
}
h3 tt,
h3 code {
font-size: inherit;
}
h4 tt,
h4 code {
font-size: inherit;
}
h5 tt,
h5 code {
font-size: inherit;
}
h6 tt,
h6 code {
font-size: inherit;
}
h1 {
font-size: 2.25em;
line-height: 1.2;
border-bottom: 1px solid #eee;
}
h2 {
font-size: 1.75em;
line-height: 1.225;
border-bottom: 1px solid #eee;
}
/*@media print {
.typora-export h1,
.typora-export h2 {
border-bottom: none;
padding-bottom: initial;
}
.typora-export h1::after,
.typora-export h2::after {
content: "";
display: block;
height: 100px;
margin-top: -96px;
border-top: 1px solid #eee;
}
}*/
h3 {
font-size: 1.5em;
line-height: 1.43;
}
h4 {
font-size: 1.25em;
}
h5 {
font-size: 1em;
}
h6 {
font-size: 1em;
color: #777;
}
p,
blockquote,
ul,
ol,
dl,
table{
margin: 0.8em 0;
}
li>ol,
li>ul {
margin: 0 0;
}
hr {
height: 2px;
padding: 0;
margin: 16px 0;
background-color: #e7e7e7;
border: 0 none;
overflow: hidden;
box-sizing: content-box;
}
li p.first {
display: inline-block;
}
ul,
ol {
padding-left: 30px;
}
ul:first-child,
ol:first-child {
margin-top: 0;
}
ul:last-child,
ol:last-child {
margin-bottom: 0;
}
blockquote {
border-left: 4px solid #dfe2e5;
padding: 0 15px;
color: #777777;
}
blockquote blockquote {
padding-right: 0;
}
table {
padding: 0;
word-break: initial;
}
table tr {
border: 1px solid #dfe2e5;
margin: 0;
padding: 0;
}
table tr:nth-child(2n),
thead {
background-color: #f8f8f8;
}
table th {
font-weight: bold;
border: 1px solid #dfe2e5;
border-bottom: 0;
margin: 0;
padding: 6px 13px;
}
table td {
border: 1px solid #dfe2e5;
margin: 0;
padding: 6px 13px;
}
table th:first-child,
table td:first-child {
margin-top: 0;
}
table th:last-child,
table td:last-child {
margin-bottom: 0;
}
.CodeMirror-lines {
padding-left: 4px;
}
.code-tooltip {
box-shadow: 0 1px 1px 0 rgba(0,28,36,.3);
border-top: 1px solid #eef2f2;
}
.md-fences,
code,
tt {
border: 1px solid #e7eaed;
background-color: #f8f8f8;
border-radius: 3px;
padding: 0;
padding: 2px 4px 0px 4px;
font-size: 0.9em;
}
code {
background-color: #f3f4f4;
padding: 0 2px 0 2px;
}
.md-fences {
margin-bottom: 15px;
margin-top: 15px;
padding-top: 8px;
padding-bottom: 6px;
}
.md-task-list-item > input {
margin-left: -1.3em;
}
@media print {
html {
font-size: 13px;
}
table,
pre {
page-break-inside: avoid;
}
pre {
word-wrap: break-word;
}
}
.md-fences {
background-color: #f8f8f8;
}
#write pre.md-meta-block {
padding: 1rem;
font-size: 85%;
line-height: 1.45;
background-color: #f7f7f7;
border: 0;
border-radius: 3px;
color: #777777;
margin-top: 0 !important;
}
.mathjax-block>.code-tooltip {
bottom: .375rem;
}
.md-mathjax-midline {
background: #fafafa;
}
#write>h3.md-focus:before{
left: -1.5625rem;
top: .375rem;
}
#write>h4.md-focus:before{
left: -1.5625rem;
top: .285714286rem;
}
#write>h5.md-focus:before{
left: -1.5625rem;
top: .285714286rem;
}
#write>h6.md-focus:before{
left: -1.5625rem;
top: .285714286rem;
}
.md-image>.md-meta {
/*border: 1px solid #ddd;*/
border-radius: 3px;
padding: 2px 0px 0px 4px;
font-size: 0.9em;
color: inherit;
}
.md-tag {
color: #a7a7a7;
opacity: 1;
}
.md-toc {
margin-top:20px;
padding-bottom:20px;
}
.sidebar-tabs {
border-bottom: none;
}
#typora-quick-open {
border: 1px solid #ddd;
background-color: #f8f8f8;
}
#typora-quick-open-item {
background-color: #FAFAFA;
border-color: #FEFEFE #e5e5e5 #e5e5e5 #eee;
border-style: solid;
border-width: 1px;
}
/** focus mode */
.on-focus-mode blockquote {
border-left-color: rgba(85, 85, 85, 0.12);
}
header, .context-menu, .megamenu-content, footer{
font-family: "Segoe UI", "Arial", sans-serif;
}
.file-node-content:hover .file-node-icon,
.file-node-content:hover .file-node-open-state{
visibility: visible;
}
.mac-seamless-mode #typora-sidebar {
background-color: #fafafa;
background-color: var(--side-bar-bg-color);
}
.md-lang {
color: #b4654d;
}
/*.html-for-mac {
--item-hover-bg-color: #E6F0FE;
}*/
#md-notification .btn {
border: 0;
}
.dropdown-menu .divider {
border-color: #e5e5e5;
opacity: 0.4;
}
.ty-preferences .window-content {
background-color: #fafafa;
}
.ty-preferences .nav-group-item.active {
color: white;
background: #999;
}
.menu-item-container a.menu-style-btn {
background-color: #f5f8fa;
background-image: linear-gradient( 180deg , hsla(0, 0%, 100%, 0.8), hsla(0, 0%, 100%, 0));
}
:root {--mermaid-font-zoom:1em ;} @media print { @page {margin: 0 0 0 0;} body.typora-export {padding-left: 0; padding-right: 0;} #write {padding:0;}}
目录
技术概要: Globals 1
什么是 Globals? 1
为什么要学习 Globals? 1
试一试: 访问 Globals 的三种方式 2
用前须知 2
导入和检查类定义 2
导入示例数据并检查 Globals 3
关系访问 Globals(Accessing Globals Relationaly) 5
将 Globals 作为对象访问(Accessing Globals as Objects) 6
直接访问 Globals(Accessing Globals Directly) 7
有关 Globals 的更多信息 8
使用 InterSystems IRIS API 访问 Globals 9
了解有关 Globals 的更多信息 10
Globals 及其结构 10
多模型开发 10
InterSystems Native API 10
技术概要: Globals
本文档向您介绍了 globals 的概念,globals是 InterSystems IRIS®数据平台的底层存储结构。我们将向您展示如何使用关系模型和对象模型访问 globals,以及如何直接访问 globals。
要浏览所有的技术概要(First Look),包括可以在 InterSystems IRIS 免费的评估实例上执行的那些 ,请参见 InterSystems First Looks(《InterSystems 技术概要》)。
什么是 Globals?
InterSystems IRIS 数据平台的特点之一是它能够一次性存储数据,并允许您使用多个范式(paradigm)来访问它。例如,您可以使用 InterSystems SQL 将数据可视化为行和列,或者您可以使用 ObjectScript 将数据视为具有属性和方法的对象。您的应用程序甚至可以混合使用这两种数据模型,对于给定的任务使用最简单和更有效的模型。但是无论您如何访问数据,InterSystems IRIS 都将其存储在被称为 globals 的底层数据结构中。
Globals 可以被认为是持久化多维稀疏数组(persistent multidimensional sparse arrays):
持久化(Persistent)------Globals 存储在数据库中,可以在任何时候被任何可以访问该数据库的进程(process)检索到。
多维(Multidimensional)------global 节点可以有任意数量的下标。这些下标可以是整数、小数,或字符串。
稀疏(Sparse)------节点下标不必是连续的,这意味着没有存储值的下标不会使用任何存储。
Global 节点可以存储多种类型的数据,包括:
字符串
数字数据
字符或二进制数据流
数据集合,如列表或数组
对其他存储位置的引用
即使是您编写的服务器端代码,最终也存储在 globals 中!
为什么要学习 Globals?
在了解很少或几乎不了解 globals 的情况下,虽然也可以在 InterSystems IRIS 平台上编写应用程序,但出于以下几个原因,您可能想了解有关它们的更多信息:
如果您直接访问 globals,有些操作可能会更容易或更有效。
您可能希望为不符合关系或对象数据模型的数据创建自定义数据结构。
试一试: 访问 Globals 的三种方式
有些系统管理任务是在 global 层面完成的,了解 globals 将使这些任务对您更有意义。
试一试:访问 Globals 的三种方式
在本文档中,您将检查用于存储 U.S. 州类对象的数据的 globals。该类的属性包括州名、双字母邮政缩写、首府、建州年份和面积(单位:平方英里)。然后,您将使用关系和对象技术,以及直接操作 globals 来访问和存储这个类的对象。
用前须知
要使用这个技术概要(First Look),您需要一个正在运行的 InterSystems IRIS 实例。您的选择包括几种类型的已授权的和免费的评估实例;该实例不需要由您正在工作的系统托管(尽管您的系统必须能够通过网络访问该实例)。关于如何部署每种类型的实例的信息(如果您还没有可使用的实例),请参见 InterSystems IRIS Basics: Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中的 Deploying InterSystems IRIS(部署 InterSystems IRIS)。
您也需要知道:
实例的基于 web 的管理门户(Management Portal)的 URL,这是 InterSystems IRIS 的系统管理用户界面。
如何访问终端(Terminal),InterSystems IRIS 命令行工具。
实例的用户名和密码(InterSystems Labs 上的 web 实例不需要)。
您还需要从 InterSystems GitHub repo :https://github.com/intersystems/First- Look-Globals 下载两个示例文件。
FirstLookGlobals.xml 包含 State 类的类定义。
FirstLookGlobals.gof 包含了 U.S. 最初 13 个州的一些 global 示例数据。
关于如何访问管理门户(Management Portal )或终端(Terminal)的更多信息,请参见 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中的"InterSystems IRIS Connection Information(InterSystems IRIS 连接信息)"。您实际上并不需要一个 IDE 来做这些练习。
导入和检查类(Class)定义
首先,将 State 类定义导入 InterSystems IRIS:
从管理门户(Management Portal)的主页,选择 System Explorer(系统资源管理器) > Classes(类)。
在 Classes 页面上,查看左栏,确保您在 USER 命名空间。您可以把命名空间看作是工作空间或目录。
点击 Import(导入)。
在 Import Classes 的对话框中: a. 如果您的 InterSystems IRIS 实例在远程服务器上运行,请指定是将示例文件下载到远程服务器还是下载到您的本地计算机。 b. 在 File 或 Directory 的 Import(导入)区域,点击 File(文件)。 c. 浏览您从 GitHub 下载的 FirstLookGlobals.xml 文件。
试一试: 访问 Globals 的三种方式
d. 选择 Compile Imported Items(编译导入项)。
e. 对于 Compile Flags(编译标志),指定 cuk。
f. 点击 Next(下一步)。
g. 点击 Import(导入)。
h. 当出现加载成功的消息时,点击 Done(完成)。
现在,在 Classes 页面,您应该看到 FirstLook.State.cls 在类的列表中。在 InterSystems IRIS 中,包含类的包名称(FirstLook)附加有类的名称(State)。扩展名 .cls 用来表示类文件。
注意: 如果您的命名空间包含大量的类,可以在页面左栏的 Class Name(类名) 框中输入 F*.cls 来过滤列表。
在 FirstLook.State.cls 类的右侧,点击 Documentation(文档) 来查看为该类生成的文档。
您会注意到的第一件事是 FirstLook.State 类扩展了 %Persistent 类,这意味着该类的数据将存储在数据库中 (系统定义的类和方法通常以 % 开头) 。
persistent class FirstLook.State extends %Persistent
扩展 %Persistent 还提供了一些方法,您可以使用这些方法在该类上执行操作。例如,它允许您创建该类的新对象或从数据库访问对象并将其加载到内存中。
再往下看,您可以看到这个类有五个属性:Area、Capital、Established、Name 和 PostalAbbr。
property Area as %Integer; property Capital as %String; property Established as %Integer;
property Name as %String [ Required ]; property PostalAbbr as %String;
这个类还有两个索引,CapitalIndex 和 PostalAbbrIndex,这两个索引可以加快 SQL 查询的速度,并允许您通过首府和邮政缩写快速查找州。
index (CapitalIndex on Capital) [Unique];
index (PostalAbbrIndex on PostalAbbr) [Unique];
导入示例数据并检查 Globals
要了解存储 State 类对象的 globals,首先要导入一些数据:
从管理门户(Management Portal)的主页,选择 System Explorer(系统资源管理器) > Globals。(或从 Classes 页面,点击 Globals 按钮。)
在 Globals 页面上,查看左栏,确保您在 USER 命名空间。
点击 Import(导入)。
在 Import Globals 对话框中: a. 如果您的 InterSystems IRIS 实例在远程服务器上运行,请指定是将示例文件下载到远程服务器还是下载到您的本地计算机。 b. 浏览您从 GitHub 下载的 FirstLookGlobals.gof 文件。 c. 点击 Next(下一步)。 d. 点击 Import(导入)。
试一试: 访问 Globals 的三种方式
e. 当出现加载成功的消息时,点击 Done(完成)。
现在,在 Globals 页面上,您应该看到 FirstLook.StateD 和 FirstLook.StateI 这两个 globals 在列表中。默认情况下,类(class)的数据存储在名称后面加 Dappended 的 global 中,索引存储在名称后面加 Iappended 的 global 中。最常见的情况是,您会看到 globals 名称前有一个插入符号(\^)。
注意: 如果您的命名空间包含大量的 globals,可以在页面左栏的 Global Name(Global 名称) 框中输入 F* 来过滤这个列表。
在 FirstLook.StateD global 的右边,点击 View(查看) 来显示 global 内容的列表。
\^FirstLook.StateD = 13
\^FirstLook.StateD(1) = $lb("","Delaware","DE","Dover",1787,2489)
\^FirstLook.StateD(2) = $lb("","Pennsylvania","PA","Harrisburg",1787,46054)
\^FirstLook.StateD(3) = $lb("","New Jersey","NJ","Trenton",1787,8723)
\^FirstLook.StateD(4) = $lb("","Georgia","GA","Atlanta",1788,59425)
\^FirstLook.StateD(5) = $lb("","Connecticut","CT","Hartford",1788,5543)
\^FirstLook.StateD(6) = $lb("","Massachusetts","MA","Boston",1788,10554)
\^FirstLook.StateD(7) = $lb("","Maryland","MD","Annapolis",1788,12406)
\^FirstLook.StateD(8) = $lb("","South Carolina","SC","Columbia",1788,32020)
\^FirstLook.StateD(9) = $lb("","New Hampshire","NH","Concord",1788,9349)
\^FirstLook.StateD(10) = $lb("","Virginia","VA","Richmond",1788,42775)
\^FirstLook.StateD(11) = $lb("","New York","NY","Albany",1788,54555)
\^FirstLook.StateD(12) = $lb("","North Carolina","NC","Raleigh",1789,53819)
\^FirstLook.StateD(13) = $lb("","Rhode Island","RI","Providence",1790,1545)
您可以看到,每个状态的节点都有一个整数的下标,称为对象 ID(或简称 ID),它是在您存储这个类的新对象时由系统生成的。Global 的根节点,没有下标,包含一个计数器,该计数器递增以生成下一个 ID。
每个节点的数据按照在类定义中指定的顺序存储为属性列表。如果查看 \^FirstLook.StateD(3),您可以看到州名是新泽西州(New Jersey),邮政缩写是 NJ,首府是特伦顿(Trenton),该州于 1787 年加入联邦(Union),面积为 8723 平方英里。
点击 Cancel(取消) 返回 globals 列表,然后点击 global FirstLook.StateI 旁边的 View(查看) 查看 State 类的索引。
\^FirstLook.StateI("CapitalIndex"," ALBANY",11) = ""
\^FirstLook.StateI("CapitalIndex"," ANNAPOLIS",7) = ""
\^FirstLook.StateI("CapitalIndex"," ATLANTA",4) = ""
\^FirstLook.StateI("CapitalIndex"," BOSTON",6) = ""
\^FirstLook.StateI("CapitalIndex"," COLUMBIA",8) = ""
\^FirstLook.StateI("CapitalIndex"," CONCORD",9) = ""
\^FirstLook.StateI("CapitalIndex"," DOVER",1) = ""
\^FirstLook.StateI("CapitalIndex"," HARRISBURG",2) = ""
\^FirstLook.StateI("CapitalIndex"," HARTFORD",5) = ""
\^FirstLook.StateI("CapitalIndex"," PROVIDENCE",13) = ""
\^FirstLook.StateI("CapitalIndex"," RALEIGH",12) = ""
\^FirstLook.StateI("CapitalIndex"," RICHMOND",10) = ""
\^FirstLook.StateI("CapitalIndex"," TRENTON",3) = ""
\^FirstLook.StateI("PostalAbbrIndex"," CT",5) = ""
\^FirstLook.StateI("PostalAbbrIndex"," DE",1) = ""
\^FirstLook.StateI("PostalAbbrIndex"," GA",4) = ""
\^FirstLook.StateI("PostalAbbrIndex"," MA",6) = ""
\^FirstLook.StateI("PostalAbbrIndex"," MD",7) = ""
\^FirstLook.StateI("PostalAbbrIndex"," NC",12) = ""
\^FirstLook.StateI("PostalAbbrIndex"," NH",9) = ""
\^FirstLook.StateI("PostalAbbrIndex"," NJ",3) = ""
\^FirstLook.StateI("PostalAbbrIndex"," NY",11) = ""
\^FirstLook.StateI("PostalAbbrIndex"," PA",2) = ""
\^FirstLook.StateI("PostalAbbrIndex"," RI",13) = ""
\^FirstLook.StateI("PostalAbbrIndex"," SC",8) = ""
\^FirstLook.StateI("PostalAbbrIndex"," VA",10) = ""
仔细看看 global \^FirstLook.StateI 中的第一个节点。这里,第一个下标("CapitalIndex")是索引的名称,第二个下标是被索引的属性的值("ALBANY"),第三个下标是以奥尔巴尼(Albany)为首府的州的 ID(11)。如果您回顾一下 global 数据,您会发现 \^FirstLook.StateD(11) 是纽约州(New York)。
Globals 使用数组下标自动按排序顺序存储。
试一试: 访问 Globals 的三种方式
关系访问 Globals (Accessing Globals Relationally)
现在,看看为 State 类生成的 InterSystems IRIS 表:
从管理门户(Management Portal)的主页,选择 System Explorer(系统资源管理器) > SQL。
在 SQL 页面上,查看页面的顶部,确保您在 USER 名称空间。 如果不是,请点击 Switch(切换)来改更改命名空间。
在左栏中,展开 Tables(表)部分来查看命名空间中的表。
在 Tables 下,点击 FirstLook.State 表。
在 Catalog Details(目录详情) 标签上,点击 Fields(字段),您将看到为 State 类的每个属性生成的字段,以及称为 ID(有时称为 RowID) 的额外字段。 这个字段类似于您在类的 globals 中看到的对象 ID。
注意: 如果您的命名空间包含大量的表,可以在页面左栏的 Filter(过滤) 框中输入 F* 来过滤列表。
点击 Execute Query(执行查询) 标签,打开一个文本区,您可以在这里编写针对 FirstLook.State 表运行的查询。
输入以下查询:
SELECT * FROM FirstLook.State WHERE ID = 6
并点击 Execute(执行)。该查询返回您请求的马萨诸塞州(Massachusetts )的行。
输入以下查询:
INSERT INTO FirstLook.State(Area, Capital, Established, Name, PostalAbbr) VALUES (9616, 'Montpelier', 1791, 'Vermont', 'VT')
并点击 Execute(执行),将一行插入第 14 个州佛蒙特州(Vermont )的表中。
要查看在 FirstLook.State 表中插入一行的效果,请返回到命名空间 USER 的 Globals 页面,并再次查看 globals。
从管理门户(Management Portal)的主页,选择 System Explorer(系统资源管理器) > Globals。
在 Globals 页面上,查看左栏,确保您在 USER 命名空间。
查看数据 global,\^FirstLook.StateD,您可以看到 ID 计数器已经增加:
\^FirstLook.StateD = 14
并且一个新的节点被添加到 global:
\^FirstLook.StateD(14) = $lb("","Vermont","VT","Montpelier",1791,9616)
查看索引 global,\^FirstLook.StateI,可以看到索引已经被更新为两个新节点:
\^FirstLook.StateI("CapitalIndex"," MONTPELIER",14) = ""
和
\^FirstLook.StateI("PostalAbbrIndex"," VT",14) = ""
试一试: 访问 Globals 的三种方式
将 Globals 作为对象访问(Accesing Globals as Objects)
请记住,当您创建 State 类时,扩展了类 %Persistent,这使您可以访问一些有用的方法,这些方法使您可以在类的 globals 中存储数据并再次检索它。接下来,通过在 InterSystems 终端(Terminal)中编写一些 ObjectScript 来测试其中一些方法。如果您以前没有使用过终端(Terminal),请参见 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中的"InterSystems IRIS Connection Information(InterSystems IRIS 连接信息"。
在您启动 Terminal session (终端会话)后,您应该看到一个提示符,指示您所处的名称空间。如果您不在 USER 命名空间,执行以下命令:
set $namespace = "USER"
首先,将您刚刚用 SQL 查询添加的佛蒙特州(Vermont)的数据加载到内存中。调用 FirstLook.State 类的 %OpenId() 方法,并将返回值赋给变量 vt。%OpenId() 返回对象的"句柄(handle)",更正式地称为对象引用或 OREF。
USER>set vt = ##class(FirstLook.State).%OpenId(14)
您可以通过访问对象的 Name 属性来查看刚刚加载的状态的名称:
USER>write vt.Name
Vermont
您可以使用 zwrite 命令获取所有对象属性的摘要。该命令提供的其他信息超出了本文档的范围。
USER>zwrite vt
vt=2@FirstLook.State ; <OREF>
+----------------- general information ---------------
| oref value: 2
| class name: FirstLook.State
| %%OID: $lb("14","FirstLook.State")
| reference count: 2
+----------------- attribute values ------------------
| %Concurrency = 1 <Set>
| Area = 9616
| Capital = "Montpelier"
| Established = 1791
| Name = "Vermont"
| PostalAbbr = "VT"
+-----------------------------------------------------
要创建一个新的 State 对象,请使用 %New() 方法,该方法将一个 OREF 返回给新对象。
USER>set newstate = ##class(FirstLook.State).%New()
现在,设置第 15 个州肯塔基州(Kentucky)的属性。USER>set newstate.Name = "Kentucky" USER>set newstate.PostalAbbr = "KY" USER>set newstate.Capital = "Frankfort" USER>set newstate.Established = 1792 USER>set newstate.Area = 40408
检查所有属性。
试一试: 访问 Globals 的三种方式
USER>zwrite newstate
newstate=4@FirstLook.State ; <OREF>
+----------------- general information ---------------
| oref value: 4
| class name: FirstLook.State
| reference count: 2
+----------------- attribute values ------------------
| %Concurrency = 1 <Set>
| Area = 40408
| Capital = "Frankfort"
| Established = 1792
| Name = "Kentucky"
| PostalAbbr = "KY"
+-----------------------------------------------------
如果您对一切看起来很满意,通过调用新对象的 %Save() 方法将对象保存到磁盘。%Save() 方法返回一个状态,如果保存成功,该状态的值为 1。
USER>set status = newstate.%Save()
USER>write status
1
再一次,通过进入管理门户(Management Portal)中的 Globals 页面来检查您的工作。查看数据 global,
\^FirstLook.StateD,您可以看到 ID 计数器再次增加:
\^FirstLook.StateD = 15
并且一个新的节点被添加到 global:
\^FirstLook.StateD(15) = $lb("","Kentucky","KY","Frankfort",1792,40408)
查看索引 global,\^FirstLook.StateI,可以看到索引已经被更新为两个新节点:
\^FirstLook.StateI("CapitalIndex"," FRANKFORT",15) = ""
和
\^FirstLook.StateI("PostalAbbrIndex"," KY",15) = ""
直接访问 Globals(Accessing Globals Directly)
虽然 InterSystems IRIS 中的数据最常见的是通过 SQL 或使用对象层来访问,但您也可以直接访问扩展 %Persistent 的类的 globals。这种方法比较棘手,因为您需要知道 global 的结构。
首先,找到 ID 为 15 的州名称。
在终端(Terminal)中,用下标 15 将变量 ky 赋给数据 global 中的节点。
USER>set ky = \^FirstLook.StateD(15)
您可以使用 zwrite 检查存储在这个节点上的值:
USER>zwrite ky
ky=$lb("","Kentucky","KY","Frankfort",1792,40408)
接下来,使用 $list() 函数来获取列表中的第二项:
USER>write $list(ky, 2)
Kentucky
根据您在使用 SQL 或对象方法添加状态后检查 globals 所学到的内容,编写一些代码来添加新状态。
首先,准备数据,将每个属性(从对象的角度考虑)或字段(从 SQL 的角度考虑)放入不同的变量。
试一试: 访问 Globals 的三种方式
USER>set name = "Tennessee"
USER>set postalabbr = "TN"
USER>set capital = "Nashville"
USER>set established = 1796
USER>set area = 42144
然后使用 $listbuild() 函数构建可以存储的属性列表。
USER>set properties = $listbuild("", name, postalabbr, capital, established, area)
USER>zwrite properties
properties=$lb("","Tennessee","TN","Nashville",1796,42144)
使用一个 ObjectScript 语句,增加 \^FirstLook.StateD global 的 ID 计数器,并将新值赋给变量 id。
USER>set id = $increment(\^FirstLook.StateD)
USER>write \^FirstLook.StateD
16
USER>write id
16
现在,将数据存储在数据 global 中。
USER>set \^FirstLook.StateD(id) = properties
USER>zwrite \^FirstLook.StateD(id)
\^FirstLook.StateD(16)=$lb("","Tennessee","TN","Nashville",1796,42144)
现在我们需要手动更新索引,否则在首府(Capital )或邮政缩写(PostalAbbr)上,带有 WHERE 子句的 SQL 查询将不包括田纳西州(Tennessee)。这个过程比存储数据要复杂一些。
对于字符串值(string value)的索引,InterSystems IRIS 将字符串转换为大写字母,并在前面添加一个空格字符,以便于排序。使用 _运算符将一个空格连接到大写字母的前面,然后使用 $zconvert() 函数将其转换为大写字母。然后对邮政缩写执行相同操作。
USER>set capital = $zconvert(" "_capital, "U")
USER>set postalabbr = $zconvert(" "_postalabbr, "U")
最后,将索引条目存储在索引 global 中。
USER>set \^FirstLook.StateI("CapitalIndex", capital, id) = ""
USER>set \^FirstLook.StateI("PostalAbbrIndex", postalabbr, id) = ""
为确保您正确完成工作,请进入管理门户(Management Portal)中的 Globals 页面,并查看
\^FirstLook.StateD 和 \^FirstLook.StateI globals。您也可以使用 zwrite \^FirstLook.StateD 和
zwrite \^FirstLook.StateI 从终端(Terminal)显示每个 global 的完整内容。
有关 Globals 的更多信息
使用 SQL 创建 Globals
在本文档中,您所看到的 globals 是通过存储使用类定义(class definition)指定的类的对象(object)创建的。您可以通过使用 SQL 创建表和表的索引来创建结构非常相似的 globals。然后,InterSystems IRIS 将根据您创建的表为您生成一个类。
作为练习,进入管理门户(Management Portal)中 USER 命名空间的 SQL 页面,并使用 Execute Query(执行查询)标签执行下列语句。
使用 InterSystems IRIS API 访问 Globals
CREATE TABLE FirstLook.SQL (%CLASSPARAMETER USEEXTENTSET 0, %CLASSPARAMETER DEFAULTGLOBAL =
'\^FirstLook.SQL',
Name CHAR(30) NOT NULL, PostalAbbr CHAR(2), Capital CHAR(30), Established INT, Area INT) CREATE UNIQUE INDEX CapitalIndex ON FirstLook.SQL (Capital)
CREATE UNIQUE INDEX PostalAbbrIndex ON FirstLook.SQL (PostalAbbr) INSERT INTO FirstLook.SQL (Name, PostalAbbr, Capital, Established, Area) VALUES ('Maine', 'ME', 'Augusta', 1820, 35380)
在 SQL 页面的左栏中,您现在应该看到 FirstLook.SQL 表。
进入 Classes 页面,找到类 FirstLook.SQL.cls 并查看其文档。您注意到有什么不同吗?这个类有一个额外的索引,称为位图扩展索引(Bitmap Extent Index)。然后进入 Globals 页面,找到 \^FirstLook.SQLD 和 \^FirstLook.SQLI globals。看看 \^FirstLook.SQLI,并看看您是否能找到额外的索引。
创建自定义 Globals
到目前为止,您已经看到了扩展 %Persistent 类时创建的 globals。但是,globals 可用于存储无模式的数据,这些数据可能不适合类或关系范式。例如,使用终端(Terminal)或管理门户(Management Portal),切换到 %SYS 命名空间,并检查 \^CONFIGglobal,它存储了一些 InterSystems IRIS 配置设置。下面是 \^CONFIGglobal 示例的一部分:
\^CONFIG("Cluster","CommIPAddress") = ""
\^CONFIG("Cluster","JoinCluster") = 0
\^CONFIG("ConfigFile","Version") = "2018.20"
\^CONFIG("Conversions","LastConvertTime") = "2019-03-13 08:39:45"
\^CONFIG("Databases","ENSLIB") = "/usr/irissys/mgr/enslib/"
\^CONFIG("Databases","IRISAUDIT") = "/usr/irissys/mgr/irisaudit/"
\^CONFIG("Databases","IRISLIB") = "/usr/irissys/mgr/irislib/"
\^CONFIG("Databases","IRISLOCALDATA") = "/usr/irissys/mgr/irislocaldata/"
\^CONFIG("Databases","IRISSYS") = "/usr/irissys/mgr/"
\^CONFIG("Databases","IRISTEMP") = "/usr/irissys/mgr/iristemp/"
\^CONFIG("Databases","USER") = "/usr/irissys/mgr/user/"
如果您想创建和存储自己的自定义数据结构,您可以使用 ObjectScript 轻松做到。使用下面的示例,您可以编写几行代码定义一个有向图来存储机场之间的机票价格:
USER>set \^Fares("BOS", "ORD") = 87
USER>set \^Fares("ORD", "BOS") = 63
USER>set \^Fares("BOS", "LAX") = 143
USER>set \^Fares("LAX", "BOS") = 143
USER>set \^Fares("ORD", "LAX") = 57
USER>set \^Fares("LAX", "ORD") = 94
USER>zwrite \^Fares
\^Fares("BOS","LAX")=143
\^Fares("BOS","ORD")=87
\^Fares("LAX","BOS")=143
\^Fares("LAX","ORD")=94
\^Fares("ORD","BOS")=63
\^Fares("ORD","LAX")=57
使用 InterSystems IRIS API 访问 Globals
如果您正在用 Java、.NET、Node.js 或 Python 编写应用程序,InterSystems IRIS 提供的 API 允许您使用本文中讨论的三种模型来操作您的数据库:
通过 JDBC、ADO.NET 或 PyODBC API 进行关系访问
通过 InterSystems XEP API 访问对象
通过 InterSystems Native API 直接访问 globals
了解有关 Globals 的更多信息
现在您知道了,无论您决定如何存储或访问数据,您所做的就是使用 globals。
注意: 并非所有语言都支持所有形式的访问。
了解有关 Globals 的更多信息
使用下面列出的参考资料来了解更多有关 globals 和如何访问它们的信息。
Globals 及其结构
Globals QuickStart(Globals 快速入门)------提供 global 结构的可视化视图,并给出在自定义 global 结构中存储数据的示例。
Using Globals(《使用 Globals》)------讨论 Globals 的结构、如何管理它们以及如何使用 SQL 或 ObjectScript 访问它们。
Globals------Defining and Using Classes(定义和使用类)这部分解释了为扩展 %Persistent 类的类创建的 globals 的命名约定。
多模型开发
Multi-Model QuickStart(多模型快速入门)------描述了 InterSystems IRIS 如何允许您用各种不同的语言(包括 Java、.NET 和 ObjectScript)使用您选择的数据模型。
Java QuickStart(Java 快速入门)------向您展示如何使用 Java API 对 InterSystems IRIS 数据库进行关系、对象和直接访问。
.NET QuickStart(.NET 快速入门)------向您展示如何使用 .NET API 对 InterSystems IRIS 数据库进行关系、对象和直接访问。
Python QuickStart(Python 快速入门)------向您展示如何使用 Python API 对 InterSystems IRIS 数据库进行关系、对象和直接访问。
InterSystems Native API
Using the Native API for Java(《使用 Native API for Java》) (交互式课程)------向您展示如何使用 Native API for Java 访问 globals 以及调用类方法(call class method)和例程。
Using the Native API for Java(《使用 Native API for Java 》)(书籍)------向您展示如何使用 Native API for Java 访问 globals 以及调用类方法(call class method)和例程。
First Look: InterSystems IRIS Native API for Java(《技术概要:InterSystems IRIS Native API for Java》) --- 展示如何从 Java 应用程序访问 InterSystems IRIS globals。
Using the Native API for .NET(《使用 Native API for .NET》 )(交互式课程)------向您展示如何使用 Native API for .NET 访问 globals 以及调用类方法(call class method)和例程。
Using the InterSystems Native API for .NET(《使用 InterSystems Native API for .NET》)(书籍)------向您展示如何使用 Native API for .NET 访问 globals 以及调用类方法(call class method)和例程。
First Look: InterSystems IRIS Native API for .NET(《技术概要:InterSystems IRIS Native API for .NET》) ------展示如何从 .NET 应用程序访问 InterSystems IRIS globals。
了解有关 Globals 的更多信息
Node.js QuickStart(Node.js 快速入门)------向您展示如何使用 Native API for Node.js 访问 globals 以及调用类方法(call class method)和例程。
Using the Native API for Node.js(《使用 Native API for Node.js》)------向您展示如何使用 Native API for Python 访问 globals 以及调用类方法(call class method)和例程。
First Look: InterSystems IRIS Native API for Node.js(《技术概要:InterSystems IRIS Native API for Node.js》)-展示如何从 Node.js 应用程序访问 InterSystems IRIS globals。
Using the Native API for Python(《使用 Native API for Python》) (交互式课程)------向您展示如何使用 Native API for Python 访问 globals 以及调用类方法(call class method)和例程。
Using the Native API for Python(《使用 Native API for Python》) (书籍)------向您展示如何使用 Native API for Python 访问 globals 以及调用类方法(call class method)和例程。
First Look: InterSystems IRIS Native API for Python(《技术概要:InterSystems IRIS Native API for Python》)------展示如何从 Python 应用程序访问 InterSystems IRIS globals。
文章
Hao Ma · 四月 19, 2022
本文档只是给您一个大致的概念,方便您了解IRIS安装的方方面面。并非官方安装手册或者安装建议。生产环境的安装请仔细研究并参照[IRIS官方的安装文档](https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=AB_install#AB_install_Linux)
### 操作系统的选择
IRIS支持多种Linux系统。详细的列表请参见各个版本的支持列表,比如这个是最新的[2021IRIS的支持列表](https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=ISP_technologies#ISP_platforms_server)。需要注意的是, CentOS只支持作为测试系统, 并不支持生产系统的安装。
官方文档是以Redhat为主介绍的IRIS安装, 这是IRIS在生产环境中最常用的Linux系统之一。另一个Ubantu, InterSystems提供的docker版本是安装在Ubantu上的。
我自己测试的时候喜欢使用CentOS, 所以后面有具体安装步骤中,使用的CentOS上的记录。
### 服务器的配置
对于生产系统,安装前需要一个硬件配置方案,这个方案通常是您的项目的实施部门根据用户需求提供的。
对于测试系统,只有一个最小的磁盘的要求:1.5G。无论是实体服务器, 虚拟服务器,或者docker container,根据您要测试的内容, 一切以方便为准。如果不做性能测试,我个人经常使用的CentOS虚拟机是2核CPU, 2G或4G内存,没有运行不流畅的问题。
### 磁盘分区
标准的Linux磁盘分区并不适合IRIS的生产运行。哪怕要创建一个尽量接近生产的测试环境,建议您安装软件前要有一个完整的磁盘分区规划。在官方文档中,创建IRIS服务器分区有以下原则:
1. **IRIS程序,客户的数据库,首选Journal,备选Journal应该是分开标准分区或者逻辑盘存储的。所以至少要4个分区/逻辑盘**。
您也可能会喜欢再给backup文件和其他的比如IRIS使用的web文件添加更多的逻辑盘。
2. 文件系统方面,IRIS程序,客户的数据库推荐使用xfs文件格式,**journal盘推荐ext4格式**。( 经过专家确认,这个推荐不属于强烈推荐,更不是强制要求。大多数情况下使用xfs格式没问题。只是在大项目中,比如当您的Journal盘需要分配1TB的空间,特别是使用ECP服务器的情况下, ext4会因为更低的延时带来相对好的性能表现)
以下是一个测试系统中的分区配置,仅仅是示意。
```sh
[root@MyCentOS7 ~]# cat /etc/fstab
/dev/mapper/centos_hmscentos7-root / xfs defaults 0 0
UUID=1d1b46a2-d66d-4346-8709-e70854088b11 /boot xfs defaults 0 0
/dev/mapper/vg_iris-isc_data /isc/data xfs defaults 0 0
/dev/mapper/vg_iris-isc_iris /isc/iris xfs defaults 0 0
UUID=c9ce6576-b469-4c74-8867-fe5b5060ad62 /isc/j1 ext4 defaults 1 2
UUID=0be8a20a-b76c-4a17-9018-ecea1964b73b /isc/j2 ext4 defaults 1 2
/dev/mapper/centos_hmscentos7-swap swap swap defaults 0 0
[root@hmsCentOS7 ~]#
```
这是一个生产环境的配置实例, 其中/isc/iris是iris安装路径:下面放系统的文件,系统使用的数据库,以及和系统工作相关的文件等等,通常分配100-200G。其他的逻辑盘按客户需要分配。SWAP, /boot, /home, /var等等的配置按Linux的推荐及客户的方案配置。
| **Mount Point** | **VG** | **LV** | Size | **File System** | **Mount Options** |
| :-------------- | :------ | :-------- | :--- | --------------- | :---------------- |
| /isc/iris | vg_iris | lv_iris | 200G | XFS | 默认, nobarrier |
| /isc/db | vg_iris | lv_irisdb | 1TB | XFS | 默认, nobarrier |
| /isc/jrnpri | | | 500G | EXT4 | 默认 |
| /isc/jrnsec | | | 500G | EXT4 | 默认 |
在上面的方案中, iris系统自带的数据库IRISTEMP是放在/isc/iris下的。 IRISTEMP正常情况下不会很大,但如果应用的设计很特别,或者出了什么问题,分配了200G大小的/isc/iris可能不足够。如果生产环境发现IRISTEMP有过大的风险,您可能需要单独给IRISTEMP分配一个逻辑盘。
###优化服务器内存配置
以下的对服务器内存的设置可以提高IRIS的性能。
**使用HugePage内存**
IRIS会自动使用系统配置的HugePage, 这会提高IRIS的内存使用效率。在线文档有这么一句: **在超大页内存中可用的内存数量应大于待分配的共享内存总数;否则,将不会使用超大页内存**。 因为 内存数据的总数是为Global, Routine, Lock等分配的内存的和。可以简单的从IRIS启动的日志message.log里看到。
比如下面IRIS被分配了8913M的总内存:
```sh
12/24/21-16:28:58:490 (14080) 0 [Generic.Event] Allocated 8913MB shared memory: 8003MB global buffers, 300MB routine buffers
```
另外,因为操作系统自身的进程不会使用HugePage内存, 您也不能把内存都设置成HugePage。所以设置为**比IRIS需要的多一点就好**。
我们来看看配置HugePage的一个简单例子
```bash
# 查看服务器物理内存
[root@hmsCentOS7 ~]# cat /proc/meminfo | grep MemTotal
MemTotal: 995676 kB
#查看HugePage配置
[root@hmsCentOS7 ~]# cat /proc/meminfo | grep Huge
AnonHugePages: 67584 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
# 修改配置,分配256个2M的HugePage
[root@hmsCentOS7 ~]# vi /etc/sysctl.conf
[root@hmsCentOS7 ~]# cat /etc/sysctl.conf | grep -v ^#
vm.nr_hugepages=256
#load新配置
[root@hmsCentOS7 ~]# sysctl -p
vm.nr_hugepages = 256
[root@hmsCentOS7 ~]
[root@hmsCentOS7 ~]# cat /proc/meminfo | grep Huge
AnonHugePages: 6144 kB
HugePages_Total: 256
HugePages_Free: 256
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
[root@hmsCentOS7 ~]#
```
如果此时您启动IRIS, 会出现“Allocated xxxxMB shared memory using Huge Pages"的日志记录,而且能在/proc/meminfo里看到HugePage的占用情况。
**禁用THP(Transparent Huge Pages)**
InterSystems建议在IRIS服务器禁用THP。RedHat或者CentOS是默认打开的:
```SH
[root@hmsCentOS7 ~]# cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never
[root@hmsCentOS7 ~]#
```
禁用THP您需要修改/etc/default/grub中的GRUB_CMDLINE_LINUX记录,添加“transparent_hugepage=never“
```sh
# 修改文件
[root@hmsCentOS7 ~]# cat /etc/default/grub | grep GRUB_CMDLINE
GRUB_CMDLINE_LINUX="crashkernel=auto spectre_v2=retpoline rd.lvm.lv=centos_hmscentos7/root rd.lvm.lv=centos_hmscentos7/swap rhgb quiet transparent_hugepage=never"
# regenerate grub2配置
[root@hmsCentOS7 ~]# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-3.10.0-1160.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-1160.el7.x86_64.img
Found linux image: /boot/vmlinuz-0-rescue-bd06ad08438443f5a959cb7c0c264e89
Found initrd image: /boot/initramfs-0-rescue-bd06ad08438443f5a959cb7c0c264e89.img
done
#重启
[root@hmsCentOS7 ~]shutdown -r now
# 确认配置成功
[root@hmsCentOS7 ~]# cat /sys/kernel/mm/transparent_hugepage/enabled
always madvise [never]
[root@hmsCentOS7 ~]#
```
> [Redhat文档:配置THP](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/performance_tuning_guide/sect-red_hat_enterprise_linux-performance_tuning_guide-configuring_transparent_huge_pages)
**Dirty Page Cleanup**
在一个大内存(比如大于8G)的Linux系统中,以下参数的修改会提高大量flat-files的写性能,比如大量的文件拷贝或者IRIS backup。
- dirty-background_ratio: InterSystems建议设置为5
- dirty_ratio: InterSystems建议设置为10
您需要修改/etc/sysctl.conf文件, 添加这两行:
```sh
vm.dirty_background_ratio=5
vm.dirty_ratio=10
```
###配置NTP服务
各个数据库服务直接以及数据库服务器和应用服务,Web服务,打印服务等等之间要求精准的时间同步。客户可以自己选择采用chornyd或者ntpd来配置NTP。而且, 每个IRIS服务器推荐配置至少2个NTP Server地址。
有关配置NTP的方法请参考相关文档。
比如:[Redhat文档: CONFIGURING NTP USING THE CHRONY SUITE](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system_administrators_guide/ch-configuring_ntp_using_the_chrony_suite#sect-differences_between_ntpd_and_chronyd)
### 安装Web Server (optional)
IRIS提供Web服务需要单独安装的Web服务器。在Linux系统,IRIS支持Apache Web Server和Nginx。
生产环境中, 推荐将Web Server和IRIS安装在不同的硬件服务器上。但是, **如果是要将Web服务器和IRIS安装在同一台服务器,那么最好最好先装好Web Server, 再安装IRIS。**
在执行IRIS的安装脚本时,会提示用户是否需要连接那么先装Apache Web Server和Nginx是正确的顺序, 这样安装IRIS的时候可以将IRIS的Web服务组件,IRIS_WebGateway安装到Apache Web Server的安装目录,并生成相应的配置文件。
```sh
# 修改httpd状态的常用命令
systemctl start httpd.service #启动apache
systemctl stop httpd.service #停止apache
systemctl restart httpd.service #重启apache
#设置开机启动
sudo systemctl enable httpd.service #设置开机启动
```
> 如果启动httpd显示错误“httpd: Could not reliably determine the server's fully qualified domain name”,您需要修改httpd.conf文件, 添加ServerName, 比如设为ServerName localhost:80
**到这里, 您已经基本完成了安装IRIS的准备工作,下面是IRIS的安装步骤。**
### 加载IRIS安装软件
```sh
# 解压安装文件
[root@hmsCentOS7 ~]# mkdir /tmp/iriskit
[root@hmsCentOS7 ~]# chmod og+rx /tmp/iriskit
[root@hmsCentOS7 ~]# umask 022
[root@hmsCentOS7 ~]# gunzip -c IRIS-2022.1.0.140.0-lnxrh7x64.tar.gz | (cd /tmp/iriskit; tar xf -)
[root@hmsCentOS7 iriskit]# cd /tmp/iriskit/IRIS-2022.1.0.140.0-lnxrh7x64/
[root@hmsCentOS7 IRIS-2022.1.0.140.0-lnxrh7x64]# ls
LICENSE NOTICE cplatname dist docs irisinstall irisinstall_client irisinstall_silent kitlist lgpl.txt package tools
```
> tar -zxvf *.tar.gz是centos上常用的解压命令。上面使用的gunzip来着文档,据说是更通用,适合无法用tar来操作.gz文件的linux系统环境。
###安装依赖的软件包
建议执行IRIS安装脚本前先检查需要的软件包。
```sh
# 查看安装需要的软件包
[root@hmsCentOS7 IRIS-2022.1.0.140.0-lnxrh7x64]# ./irisinstall --prechecker
Your system type is 'Red Hat Enterprise Linux (x64)'.
Checking Requirements ...
Requirement for openssl version 1.0.2 is satisfied.
Requirement for zlib version 1.2.7 is satisfied.
[root@hmsCentOS7 IRIS-2022.1.0.140.0-lnxrh7x64]#
```
除此以外,以下软件包是按情况可选的:
- snmpd: 如果您需要使用SNMP来监控IRIS
- jre或者jdk : 如果您需要IRIS服务器使用JDBC连接其他数据库
- unixODBC: 如果您需要IRIS服务器使用ODBC连接其他数据库
- policycoreutils-python, policycoreutils-devel, settroubleshoot-server : 如果您需要使用SELinux管理IRIS文件的读写。
它们只是IRIS工作时需要的软件包,IRIS的安装并不依赖或者检查它们。
###创建iris用户
安装iris需要root用户或者拥有root权限的sudoer。然而,按照Linux的常规做法,出于安全的考虑,IRIS的管理和运行应该拥有自己的用户和用户组。在安装过程中, 您会被要求提供以下的内容:
- What user should be the owner of this instance?
- What group should be allowed to start and stop?
"owner of instance"和“group to start and stop"可以是一个用户和它的用户组。比如您创建了一个irisowner的用户, 它默认的用户组irisowner可以作为“group start to stop"。当然您也可以专门创建一个用户组, 比如irisadmin, 将您的管理员tom, jerry, mickey等等加入irisadmin。
在标准的安装步骤下, 用户组irisowner和用户组irisadmin权限相同, 因此最简单的方式就是使用irisowner用户和irisowner用户组。
```sh
# 创建iris owner
useradd irisowner
# 创建您的管理员团队
[root@hmsCentOS7 mail]# useradd -N tom
[root@hmsCentOS7 mail]# useradd -N jerry
[root@hmsCentOS7 mail]# useradd -N iscbackup
[root@hmsCentOS7 mail]# gpasswd irisowner -a tom
Adding user tom to group irisowner
[root@hmsCentOS7 mail]# gpasswd irisowner -a jerry
Adding user jerry to group irisowner
[root@hmsCentOS7 mail]# gpasswd irisowner -a iscbackup
Adding user iscbackup to group irisowner
[root@hmsCentOS7 mail]# cat /etc/group | grep irisowner
irisowner:x:1000:tom,jerry,iscbackup
[root@hmsCentOS7 mail]#
```
*如果需要,您可以把tom, jerry等用户加入sudoer列表。*
**实际上, 在后面安装脚本的执行过程中, 还有2个重要的用户被创建出来, 他们是:**
- **irisusr**: 所有iris进程使用这个user运行。它还用来访问数据库和journal。在一个安全的系统里,irisusr组里就只有一个用户irisusr, 也不要添加其他的user。
- **iscagent**: 用于运行镜像使用的iscagent进程
IRIS用户和管理员不要动这两个用户。
###执行IRIS安装脚本
安装脚本会设置user, group,和安装后文件的权限,您需要在按照前检查umask, 确认设置为022。
**执行标准的安装流程**
```bash
# 开始安装步骤
[root@hmsCentOS7 iriskit]# cd /tmp/iriskit/IRIS-2022.1.0.140.0-lnxrh7x64/
[root@hmsCentOS7 IRIS-2022.1.0.140.0-lnxrh7x64]# ls
LICENSE NOTICE cplatname dist docs irisinstall irisinstall_client irisinstall_silent kitlist lgpl.txt package tools
[root@hmsCentOS7 IRIS-2022.1.0.140.0-lnxrh7x64]# ./irisinstall
Your system type is 'Red Hat Enterprise Linux (x64)'.
Currently defined instances:
Enter instance name: iris
Do you want to create InterSystems IRIS instance 'iris' ?
Enter a destination directory for the new instance.
Directory: /isc/iris
------------------------------------------------------------------
NOTE: Users should not attempt to access InterSystems IRIS while
the installation is in progress.
------------------------------------------------------------------
Select installation type.
1) Development - Install InterSystems IRIS server and all language bindings
2) Server only - Install InterSystems IRIS server
3) Custom
Setup type ? 1
How restrictive do you want the initial Security settings to be?
"Minimal" is the least restrictive, "Locked Down" is the most secure.
1) Minimal
2) Normal
3) Locked Down
Initial Security settings ? 2
What user should be the owner of this instance? irisowner
An InterSystems IRIS account will also be created for user irisowner.
Install will create the following InterSystems IRIS accounts for you:
_SYSTEM, Admin, SuperUser, irisowner and CSPSystem.
Please enter the common password for _SYSTEM, Admin, SuperUser and irisowner:
Re-enter the password to confirm it:
Please enter the password for CSPSystem:
Re-enter the password to confirm it:
What group should be allowed to start and stop
this instance? irisowner
Do you want to install IRIS Unicode support ?
InterSystems IRIS did not detect a license key file
Do you want to enter a license key ?
Please review the installation options:
------------------------------------------------------------------
Instance name: iris
Destination directory: /isc/iris
InterSystems IRIS version to install: 2022.1.0.140.0
Installation type: Development
Unicode support: Y
Initial Security settings: Normal
User who owns instance: irisowner
Group allowed to start and stop instance: irisowner
Effective group for InterSystems IRIS processes: irisusr
Effective user for InterSystems IRIS SuperServer: irisusr
SuperServer port: 1972
WebServer port: 52773
JDBC Gateway port: 53773
Web Gateway: using built-in web server
Not installing IntegratedML
------------------------------------------------------------------
Confirm InterSystems IRIS installation ?
Starting installation
Starting up InterSystems IRIS for loading...
../bin/irisinstall -s . -B -c c -C /isc/iris/iris.cpf*iris -W 1 -g2
Starting Control Process
Allocated 238MB shared memory
32MB global buffers, 80MB routine buffers
Creating a WIJ file to hold 32 megabytes of data
IRIS startup successful.
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory
System locale setting is 'en_US.UTF-8'
This copy of InterSystems IRIS has been licensed for use exclusively by:
Local license key file not found.
Copyright (c) 1986-2022 by InterSystems Corporation
Any other use is a violation of your license agreement
^^/isc/iris/mgr/>
^^/isc/iris/mgr/>
Start of IRIS initialization
Loading system routines
Updating system TEMP and LOCALDATA databases
Installing National Language support
Setting IRISTEMP default collation to IRIS standard (5)
Loading system classes
Updating Security database
Loading system source code
Building system indices
Updating Audit database
Updating Journal directory
Updating User database
Updating Interoperability databases
Scheduling inventory scan
IRIS initialization complete
See the iboot.log file for a record of the installation.
Starting up InterSystems IRIS...
Once this completes, users may access InterSystems IRIS
Starting IRIS
Using 'iris.cpf' configuration file
Starting Control Process
Global buffer setting requires attention. Auto-selected 25% of total memory.
Allocated 463MB shared memory
243MB global buffers, 80MB routine buffers
Creating a WIJ file to hold 99 megabytes of data
This copy of InterSystems IRIS has been licensed for use exclusively by:
Local license key file not found.
Copyright (c) 1986-2022 by InterSystems Corporation
Any other use is a violation of your license agreement
1 alert(s) during startup. See messages.log for details.
You can point your browser to http://hmsCentOS7:52773/csp/sys/UtilHome.csp
to access the management portal.
Installation completed successfully
[root@hmsCentOS7 IRIS-2022.1.0.140.0-lnxrh7x64]#
```
**执行customer安装IRIS+WebGateway**
如果要在本机安装WebGateway, 需要在执行安装脚本的过程中,当被问到:“Select installation type.”时选择Customer, 而不是Development。这样后面就脚本将在Web Server上加载IRIS专用的动态连接库,并创建和Web Server连接的IRIS Web网关。
在此之前, 您还需要配置安装semanage来保证可以配置SELinux。安装脚本会检查,如果没有发现semanag, 会提示您停止继续安装。
```sh
# 安装semanage, 确认命令可以工作。省略输出
[root@hmsCentOS7 ~]# yum install policycoreutils-devel
[root@hmsCentOS7 ~]# yum instll setroubleshoot-server
[root@hmsCentOS7 ~]# yum install setroubleshoot-server
[root@hmsCentOS7 ~]# semanage -h
...
[root@hmsCentOS7 ~]#
```
假设你已经创建了一个/isc/iris2的目录,然后就可以安装了。注意下面使用的superserver和web端口是51773和52774。这是默认的第2个IRIS实例的端口号,您也可以输入其他端口号或者在安装后在维护页面修改这些端口。
```sh
[root@hmsCentOS7 IRIS-2022.1.0.140.0-lnxrh7x64]# ./irisinstall
Your system type is 'Red Hat Enterprise Linux (x64)'.
Currently defined instances:
IRIS instance 'IRIS'
directory: /isc/iris
versionid: 2022.1.0.140.0
datadir: /isc/iris
conf file: iris.cpf (SuperServer port = 1972, WebServer = 52773)
status: down, last used Fri Apr 8 13:32:47 2022
product: InterSystems IRIS
Enter instance name: iris2
Do you want to create InterSystems IRIS instance 'iris2' ?
Enter a destination directory for the new instance.
Directory: /isc/iris2
------------------------------------------------------------------
NOTE: Users should not attempt to access InterSystems IRIS while
the installation is in progress.
------------------------------------------------------------------
Select installation type.
1) Development - Install InterSystems IRIS server and all language bindings
2) Server only - Install InterSystems IRIS server
3) Custom
Setup type ? 3
How restrictive do you want the initial Security settings to be?
"Minimal" is the least restrictive, "Locked Down" is the most secure.
1) Minimal
2) Normal
3) Locked Down
Initial Security settings ? 2
What user should be the owner of this instance? irisowner
An InterSystems IRIS account will also be created for user irisowner.
Install will create the following InterSystems IRIS accounts for you:
_SYSTEM, Admin, SuperUser, irisowner and CSPSystem.
Please enter the common password for _SYSTEM, Admin, SuperUser and irisowner:
Re-enter the password to confirm it:
Please enter the password for CSPSystem:
Re-enter the password to confirm it:
What group should be allowed to start and stop
this instance? irisowner
Do you want to configure additional security options ?
Do you want to install IRIS Unicode support ?
Enter the SuperServer port number :
Enter the WebServer port number :
Do you want to configure the Web Gateway to use an existing web server ? yes
Specify the WebServer type. Choose "None" if you want to configure
your WebServer manually.
1) Apache
2) None
WebServer type ? 1
Enter user name used by Apache server to run its worker processes :
Please enter location of Apache configuration file [/etc/httpd/conf/httpd.conf]:
// /etc/httpd/conf.d/isc.conf
Please enter location of Apache executable file :
Apache version 2.4 is detected.
Apache httpd server will be restarted during the install.
Please enter destination directory for Web Gateway files [/opt/webgateway]:
InterSystems IRIS did not detect a license key file
Do you want to enter a license key ?
Do you want to install IntegratedML (this feature requires additional 1166MB of disk space) ?
Please review the installation options:
------------------------------------------------------------------
Instance name: iris2
Destination directory: /isc/iris2
InterSystems IRIS version to install: 2022.1.0.140.0
Installation type: Custom
Unicode support: Y
Initial Security settings: Normal
User who owns instance: irisowner
Group allowed to start and stop instance: irisowner
Effective group for InterSystems IRIS processes: irisusr
Effective user for InterSystems IRIS SuperServer: irisusr
SuperServer port: 51773
WebServer port: 52774
JDBC Gateway port: 53773
Web Gateway: installed into /opt/webgateway
Apache web server will be configured for Web Gateway
Not installing IntegratedML
------------------------------------------------------------------
Confirm InterSystems IRIS installation ? yes
Starting installation
Updating Apache configuration file ...
- /etc/httpd/conf/httpd.conf
Starting up InterSystems IRIS for loading...
../bin/irisinstall -s . -B -c c -C /isc/iris2/iris.cpf*iris2 -W 1 -g2
Starting Control Process
Allocated 238MB shared memory
32MB global buffers, 80MB routine buffers
Creating a WIJ file to hold 32 megabytes of data
IRIS startup successful.
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory
System locale setting is 'en_US.UTF-8'
This copy of InterSystems IRIS has been licensed for use exclusively by:
Local license key file not found.
Copyright (c) 1986-2022 by InterSystems Corporation
Any other use is a violation of your license agreement
^^/isc/iris2/mgr/>
^^/isc/iris2/mgr/>
Start of IRIS initialization
Loading system routines
Updating system TEMP and LOCALDATA databases
Installing National Language support
Setting IRISTEMP default collation to IRIS standard (5)
Loading system classes
Updating Security database
Loading system source code
Building system indices
Updating Audit database
Updating Journal directory
Updating User database
Updating Interoperability databases
Scheduling inventory scan
IRIS initialization complete
See the iboot.log file for a record of the installation.
Starting up InterSystems IRIS...
Once this completes, users may access InterSystems IRIS
Starting IRIS2
Using 'iris.cpf' configuration file
Starting Control Process
Global buffer setting requires attention. Auto-selected 25% of total memory.
Allocated 463MB shared memory
243MB global buffers, 80MB routine buffers
Creating a WIJ file to hold 99 megabytes of data
This copy of InterSystems IRIS has been licensed for use exclusively by:
Local license key file not found.
Copyright (c) 1986-2022 by InterSystems Corporation
Any other use is a violation of your license agreement
1 alert(s) during startup. See messages.log for details.
You can point your browser to http://hmsCentOS7:52774/csp/sys/UtilHome.csp
to access the management portal.
Installation completed successfully
[root@hmsCentOS7 IRIS-2022.1.0.140.0-lnxrh7x64]#
```
上面步骤中当提示:”Please enter location of Apache configuration file [/etc/httpd/conf/httpd.conf]: “ 的时候我使用了默认选项/etc/httpd/conf/httpd.conf, IRIS安装脚本回修改httpd.conf文件, 加入连接IRIS的配置。这里更好的做法是先在/etc/httpd/conf.d里创建一个单独的配置文件,比如isc.conf, 在回答上面的提示是输入**/etc/httpd/conf.d/isc.conf**。很遗憾您需要自己手工先创建这个文件,安装脚本不回替您创建。
### 安装后的检查
**检查安装日志**
查看上面的安装日志,确认没有错误发生。
**查看新创建的用户irisusr和iscagent**
```sh
[root@hmsCentOS7 ~]# id irisusr
uid=1001(irisusr) gid=1001(irisusr) groups=1001(irisusr)
[root@hmsCentOS7 ~]# id iscagent
uid=1002(iscagent) gid=1002(iscagent) groups=1002(iscagent)
[root@hmsCentOS7 ~]#
```
**查看文件系统权限**
```sh
[root@hmsCentOS7 ~]# ls -l /isc
total 8
drwxr-xr-x. 2 root root 6 Apr 1 23:57 data
drwxrwxr-x. 14 irisowner irisusr 4096 Apr 6 14:28 iris
drwxr-xr-x. 3 root root 1024 Apr 1 23:57 jrnpri
drwxr-xr-x. 3 root root 1024 Apr 1 23:57 jrnsec
[root@hmsCentOS7 ~]# ls -l /isc/iris
total 112
-r--r--r--. 1 irisowner irisusr 11358 Apr 6 14:28 LICENSE
-r--r--r--. 1 irisowner irisusr 534 Apr 6 14:28 NOTICE
-rwxr-xr-x. 1 irisowner irisusr 4497 Mar 7 15:20 ODBCinstall
drwxrwxr-x. 2 irisowner irisusr 26 Apr 6 14:27 SNMP
-rwxrw-r--. 1 irisusr irisusr 9703 Apr 6 14:28 _LastGood_.cpf
drwxr-xr-x. 2 root irisowner 8192 Apr 6 14:28 bin
drwxrwxr-x. 7 irisowner irisusr 106 Apr 6 14:27 csp
drwxr-xr-x. 17 irisowner irisusr 214 Apr 6 14:28 dev
drwxrwxr-x. 3 irisowner irisusr 20 Apr 6 14:28 devuser
drwxr-xr-x. 3 root root 21 Apr 6 14:28 dist
drwxr-xr-x. 5 irisowner irisusr 156 Apr 6 14:28 docs
drwxr-xr-x. 5 irisowner irisusr 68 Apr 6 14:28 fop
drwxrwxr-x. 5 irisowner irisusr 41 Apr 6 14:27 httpd
-rw-rw-r--. 1 root root 9557 Apr 6 14:28 install.cpf
-rw-rw-r--. 1 irisowner irisusr 9732 Apr 6 14:28 iris.cpf
-rwxr-xr-x. 1 irisowner irisusr 9557 Apr 6 14:28 iris.cpf_20220406
-r-xr-x---. 4 irisowner irisowner 909 Apr 6 14:28 irisforce
-r-xr-x---. 4 irisowner irisowner 909 Apr 6 14:28 irisstart
-r-xr-x---. 4 irisowner irisowner 909 Apr 6 14:28 irisstop
-r--r--r--. 1 irisowner irisusr 7639 Apr 6 14:28 lgpl.txt
drwxr-xr-x. 6 irisowner irisusr 80 Apr 6 14:28 lib
drwxrwxr-x. 13 irisowner irisusr 4096 Apr 6 14:28 mgr
-rw-------. 1 root root 3299 Apr 6 14:28 parameters.isc
drwxr-xr-x. 2 irisowner irisusr 237 Apr 6 14:27 patrol
[root@hmsCentOS7 ~]# ls -l /isc/iris/mgr
total 163952
-rw-r-----. 1 irisowner irisusr 62914560 Apr 6 14:31 IRIS.DAT
-rw-rw----. 1 irisowner irisusr 104857600 Apr 6 14:36 IRIS.WIJ
drwxr-xr-x. 2 irisowner irisusr 4096 Apr 6 14:28 Locale
-rwxrw-r--. 1 irisusr irisusr 66 Apr 6 14:28 SystemMonitor.log
drwxrwxr-x. 2 irisusr irisusr 6 Apr 6 14:28 Temp
-rwxrw-r--. 1 irisusr irisusr 134 Apr 6 14:28 alerts.log
-rwxrw-r--. 1 irisusr irisusr 13759 Apr 6 14:28 ensinstall.log
drwxrwxr-x. 3 irisowner irisusr 36 Apr 6 14:28 enslib
-rwxr-xr-x. 1 irisowner irisusr 38319 Apr 6 14:28 iboot.log
-rwxrwxrwx. 1 irisowner irisusr 0 Apr 6 14:28 ilock
-rw-rw----. 1 irisowner irisusr 10 Apr 6 14:28 iris.ids
-rw-rw----. 1 irisowner irisusr 30 Apr 6 14:28 iris.lck
-rw-rw-rw-. 1 irisowner irisusr 2 Apr 6 14:28 iris.shid
-rw-rw-r--. 1 irisowner irisusr 5 Apr 6 14:28 iris.use
drwxrwxr-x. 3 irisowner irisusr 52 Apr 6 14:28 irisaudit
drwxrwxr-x. 3 irisowner irisusr 36 Apr 6 14:28 irislib
drwxrwxr-x. 3 irisowner irisusr 52 Apr 6 14:28 irislocaldata
-rw-rw----. 1 irisowner irisusr 933 Apr 6 14:28 irisodbc.ini
drwxrwxr-x. 3 irisowner irisusr 52 Apr 6 14:28 iristemp
drwxrwxr-x. 2 irisowner irisusr 42 Apr 6 14:28 journal
-rw-rw----. 1 irisowner irisusr 211 Apr 6 14:28 journal.log
-rw-rw-r--. 1 irisowner irisusr 14146 Apr 6 14:28 messages.log
drwxrwxr-x. 2 irisowner irisusr 6 Apr 6 14:27 python
-rw-rw-rw-. 1 irisowner irisusr 55 Apr 6 14:28 startup.last
drwxrwxr-x. 2 irisowner irisusr 6 Apr 6 14:28 stream
drwxrwxr-x. 3 irisowner irisusr 52 Apr 6 14:28 user
[root@hmsCentOS7 ~]#
```
**修改文件系统权限**
将/isc/data, /isc/jrnpri, /isc/jrnsec文件系统的user和group,以及权限修改到下面的样子
```sh
[root@hmsCentOS7 ~]# chown irisowner:irisusr /isc/data /isc/jrnpri /isc/jrnsec
[root@hmsCentOS7 ~]# chmod 775 /isc/data /isc/jrnpri /isc/jrnsec
[root@hmsCentOS7 ~]# ls -l /isc
total 8
drwxrwxr-x. 2 irisowner irisusr 6 Apr 1 23:57 data
drwxrwxr-x. 14 irisowner irisusr 4096 Apr 6 14:28 iris
drwxrwxr-x. 3 irisowner irisusr 1024 Apr 1 23:57 jrnpri
drwxrwxr-x. 3 irisowner irisusr 1024 Apr 1 23:57 jrnsec
[root@hmsCentOS7 ~]#
```
**打开防火墙IRIS的TCP端口**
IRIS系统使用以下TCP端口:
- superserver port: 默认是1972
- web port: 默认是52773
- mirror port: 默认是2188
- license server port: 默认是4001, (很少使用)
```sh
[root@hmsCentOS7 iris]# firewall-cmd --permanent --add-port=1972/tcp
success
[root@hmsCentOS7 iris]# firewall-cmd --permanent --add-port=52773/tcp
success
[root@hmsCentOS7 iris]# firewall-cmd --permanent --add-port=2188/tcp
success
[root@hmsCentOS7 iris]# firewall-cmd --list-port
1972/tcp 2188/tcp 52773/tcp
[root@hmsCentOS7 iris]# firewall-cmd --reload
success
[root@hmsCentOS7 iris]#
```
**访问系统管理界面**
通过SMP(System Management Portal)的url, 您可以访问IRIS。
http://host-ipaddr:52773/csp/sys/UtilHome.csp
用户名使用superuser, 密码为您安装创建的密码。
**激活IRIS License**
到管理界面的“系统 > 软件许可颁发 > 软件许可授权码”,加载在本机保存的IRIS许可。
注意弹出窗口的文件选项默认是.key文件。所以您上传文件到Linux服务器前最好把文件改为iris.key。另外,文件和文件夹一定要可以被irisowner访问。如果放在/root文件夹,或者不运行other用户访问,您要么在选文件的窗口无法找到这个文件,要么无法成功激活。
**创建数据库**
到 "系统 > 配置 > 本地数据库"创建数据库。查看在/isc/data里的文件夹和权限。举例:创建demo数据库到/isc/data/demo:
```sh
[root@hmsCentOS7 isc]# ls -Rl /isc/data
/isc/data:
total 0
drwxrwxr-x. 3 irisusr irisusr 52 Apr 6 15:37 demo
/isc/data/demo:
total 1028
-rw-rw----. 1 irisusr irisusr 1048576 Apr 6 15:38 IRIS.DAT
-rw-rw----. 1 irisowner irisusr 30 Apr 6 15:37 iris.lck
drwxrwxr-x. 2 irisusr irisusr 6 Apr 6 15:37 stream
/isc/data/demo/stream:
total 0
[root@hmsCentOS7 isc]#
```
**设置Journal文件夹**
到“系统 > 配置 > Journal 设置”设置journal的主备路径到/isc/jrnprm和/isc/jrnsec。
查看两个路径里的文件权限是660(rw-rw----)
```sh
[root@hmsCentOS7 opt]# ls -l /isc/jrnpri
total 272
-rw-rw----. 1 irisowner irisusr 262144 Apr 6 15:29 20220406.002
-rw-rw----. 1 irisowner irisusr 30 Apr 6 15:29 iris.lck
drwx------. 2 irisowner irisusr 12288 Apr 1 23:57 lost+found
[root@hmsCentOS7 opt]# ls -l /isc/jrnsec
total 15
-rw-rw----. 1 irisowner irisusr 30 Apr 6 15:29 iris.lck
drwx------. 2 irisowner irisusr 12288 Apr 1 23:57 lost+found
[root@hmsCentOS7 opt]#
```
**启动ISCAgent**
如果需要配置镜像,服务器需要人工启动ISCAgent
```bash
# 启动iscagent服务
systemctl start ISCAgent.service
# 设置iscagent
systemctl enable ISCAgent.service
```
**SELinux配置**(Optional)
如果您上面执行的是“**执行customer安装以安装WebGateway**”,那么这里您需要配置SELinux。
SELinux会限制httpd对系统其它文件的访问权限,比如说//usr/sbin/httpd无法访问IRIS的WebGateway, 它工作在/opt/webgateway/bin目录。你需要做以下几步来保证SELinux不再限制对IRIS文件的访问:
- 允许httpd读写WebGateway文件
```sh
# httpd_sys_content_t – set on directories that Apache is allowed access to,
# httpd_sys_rw_content_t – set on directories that Apache is allowed read/write access # httpd_sys_script_exec_t – used for directories that contain executable scripts.
[root@hmsCentOS7 conf]# ls -Z /opt/webgateway/conf
-rw-------. apache root unconfined_u:object_r:httpd_sys_content_t:s0 CSP.ini
-rw-------. apache root unconfined_u:object_r:httpd_sys_content_t:s0 CSPRT.ini
[root@hmsCentOS7 conf]# semanage fcontext -a -t httpd_sys_rw_content_t /opt/webgateway/conf/CSP.ini
[root@hmsCentOS7 conf]# restorecon -v /opt/webgateway/conf/CSP.ini
restorecon reset /opt/webgateway/conf/CSP.ini context unconfined_u:object_r:httpd_sys_content_t:s0->unconfined_u:object_r:httpd_sys_rw_content_t:s0
[root@hmsCentOS7 conf]# semanage fcontext -a -t httpd_sys_rw_content_t /opt/webgateway/conf/CSPRT.ini
[root@hmsCentOS7 conf]# restorecon -v /opt/webgateway/conf/CSPRT.ini
restorecon reset /opt/webgateway/conf/CSPRT.ini context unconfined_u:object_r:httpd_sys_content_t:s0->unconfined_u:object_r:httpd_sys_rw_content_t:s0
[root@hmsCentOS7 conf]# ls -Z
-rw-------. apache root unconfined_u:object_r:httpd_sys_rw_content_t:s0 CSP.ini
-rw-------. apache root unconfined_u:object_r:httpd_sys_rw_content_t:s0 CSPRT.ini
[root@hmsCentOS7 conf]#
[root@hmsCentOS7 webgateway]# semanage fcontext -a -t httpd_sys_rw_content_t /opt/webgateway/logs/CSP.log
[root@hmsCentOS7 webgateway]# restorecon -v /opt/webgateway/logs/CSP.log
restorecon reset /opt/webgateway/logs/CSP.log context unconfined_u:object_r:httpd_sys_content_t:s0->unconfined_u:object_r:httpd_sys_rw_content_t:s0
[root@hmsCentOS7 webgateway]#
```
- 允许httpd读写IRIS的Web Application文件,假设文件目录是/isc/web, -R是recursively
```sh
semanage fcontext -a -t httpd_sys_rw_content_t "/isc/web(/.*)?"
restorecon -Rv /isc/web/
```
- 运行httpd到IRIS的连接, (最新版本也许不需要手工配置了)
```sh
# 默认的superserver端口为1972, 上面的iris2使用的是51773
[root@hmsCentOS7 ~]# semanage port -a -t http_port_t -p tcp 51773
ValueError: Port tcp/51773 already defined
[root@hmsCentOS7 ~]# semanage port -a -t http_port_t -p tcp 1972
[root@hmsCentOS7 ~]# semanage port -l | grep http_port
http_port_t tcp 1972, 51773, 80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t tcp 5988
[root@hmsCentOS7 ~]# setsebool -P httpd_can_network_connect 1
[root@hmsCentOS7 ~]#
```
到这里, 您的IRIS安装过程已经结束了。后面的实施工作可能包括:
- IRIS配置
- 镜像配置
- WebGateway配置
我会在其他文章中介绍上述内容。
另外, 请注意重启(reboot)在安装过程中十分重要: 通常的情况是,至少有一些配置在第一次重启时并不存在。这可能包括被挂载的卷、/etc/fstab中的错误、启动时不启动的服务、在没有重载服务的情况下进行的配置修改等等。
一旦你认为服务器已经完成,并验证所有的配置都符合预期,而且应用程序仍在工作,那么重新启动服务器是非常明智的。如果不这样做,也不测试集群(例如,一次重启一个节点),可能意味着在第一次重启或HA事件中出现灾难。
*The End*