{"id":1134,"date":"2026-06-05T21:25:14","date_gmt":"2026-06-05T19:25:14","guid":{"rendered":"https:\/\/anjo.pt\/keyword-oracle\/?p=1134"},"modified":"2026-06-07T10:31:53","modified_gmt":"2026-06-07T08:31:53","slug":"asm-diskgroup-space-calculator-for-exacc","status":"publish","type":"post","link":"https:\/\/anjo.pt\/keyword-oracle\/2026\/06\/05\/asm-diskgroup-space-calculator-for-exacc\/","title":{"rendered":"ASM diskgroup space calculator for ExaCC"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">In ExaCC and probably on Exadata in OCI it is sometimes a bit complex to calculate how much space you need to add to the ASM, as you can only change the total space and the distribution. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When you just want to add 10TB (or GB) space to DATA diskgroup, you need to play a while or do an excel. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">With the calculator below, you can now do it easily:<\/p>\n\n\n\n<style data-wp-block-html=\"css\">\n.asm-table {\n  width: 100%;\n  border-collapse: collapse;\n  font-size: 14px;\n}\n\n.asm-table th {\n  font-weight: 500;\n  font-size: 12px;\n  color: var(--color-text-secondary);\n  text-align: right;\n  padding: 8px 10px;\n  border-bottom: 0.5px solid var(--color-border-tertiary);\n}\n\n.asm-table th:first-child,\n.asm-table th:nth-child(2) {\n  text-align: left;\n}\n\n.asm-table td {\n  padding: 6px 10px;\n  border-bottom: 0.5px solid var(--color-border-tertiary);\n  text-align: right;\n}\n\n.asm-table td:nth-child(2) {\n  text-align: left;\n  font-weight: 500;\n  color: var(--color-text-primary);\n}\n\n.asm-table tr.total-row td {\n  border-bottom: none;\n  font-weight: 500;\n  background: var(--color-background-secondary);\n}\n\n.asm-table input[type=number] {\n  width: 110px;\n  text-align: right;\n  font-size: 14px;\n  padding: 4px 8px;\n  box-sizing: border-box;\n}\n\n.row-label {\n  display: flex;\n  align-items: center;\n  gap: 8px;\n}\n\n.dot {\n  width: 8px;\n  height: 8px;\n  border-radius: 50%;\n  flex-shrink: 0;\n}\n\n.dot-data {\n  background: #378ADD;\n}\n\n.dot-reco {\n  background: #1D9E75;\n}\n\n.dot-sparse {\n  background: #BA7517;\n}\n\n.dot-total {\n  background: var(--color-text-secondary);\n}\n\n.unit {\n  font-size: 12px;\n  color: var(--color-text-secondary);\n  margin-left: 2px;\n}\n\n.lock-btn,\nbutton[id^=\"lock-\"] {\n  border: 1px solid #d0d0d0;\n  background: white;\n  border-radius: 4px;\n  cursor: pointer;\n  min-width: 32px;\n  height: 28px;\n  padding: 0;\n  font-size: 14px;\n}\n\nbutton[id^=\"lock-\"]:hover {\n  background: #f5f5f5;\n}\n\n#pct-lock {\n  margin-right: 6px;\n}\n\n#data-pct,\n#reco-pct,\n#sparse-pct {\n  width: 70px;\n}\n\n.input-locked {\n  background: #f0f0f0 !important;\n  color: #aaa !important;\n}\n\ntr.row-locked td {\n  background: #f5f5f5;\n}\n\n\/* Mobile *\/\n\n@media (max-width: 768px) {\n\n  .asm-table {\n    font-size: 12px;\n  }\n\n  .asm-table th,\n  .asm-table td {\n    padding: 4px 3px;\n  }\n\n  .asm-table input[type=number] {\n    width: 62px;\n    font-size: 12px;\n    padding: 2px 3px;\n  }\n\n  #data-pct,\n  #reco-pct,\n  #sparse-pct {\n    width: 45px;\n  }\n\n  .unit {\n    display: none;\n  }\n\n  .row-label {\n    gap: 4px;\n  }\n\n  button[id^=\"lock-\"] {\n    min-width: 26px;\n    height: 24px;\n    font-size: 12px;\n  }\n}\n\n\/* Very small phones *\/\n\n@media (max-width: 480px) {\n\n  .asm-table input[type=number] {\n    width: 55px;\n    font-size: 11px;\n  }\n\n  #data-pct,\n  #reco-pct,\n  #sparse-pct {\n    width: 40px;\n  }\n\n  .asm-table th {\n    font-size: 11px;\n  }\n}\n<\/style>\n\n<script data-wp-block-html=\"js\">\nconst rows = ['data', 'reco', 'sparse'];\n\nlet pctLocked = true;\nlet lockedRow = null;\n\nconst SVG_LOCKED   = '&#x1F512;';\nconst SVG_UNLOCKED = '&#x1F513;';\n\nfunction g(id)    { return document.getElementById(id); }\nfunction v(id)    { return parseFloat(g(id).value) || 0; }\nfunction round(x) { return Math.round(x * 100) \/ 100; }\n\nfunction set(id, val) {\n  g(id).value = val === null ? '' : round(val);\n}\n\nfunction setRow(row, usable) {\n  set(row + '-usable', usable);\n  set(row + '-raw',    usable * 3);\n}\n\nfunction refreshTotal() {\n  const totalU = rows.reduce((s, r) => s + v(r + '-usable'), 0);\n  set('total-usable', totalU);\n  set('total-raw',    totalU * 3);\n}\n\nfunction refreshPcts() {\n  const total = v('total-usable');\n  rows.forEach(r => {\n    const u = v(r + '-usable');\n    set(r + '-pct', total > 0 ? round(u \/ total * 100) : 0);\n  });\n}\n\nfunction recalcTotalFromRows() {\n  refreshTotal();\n  refreshPcts();\n}\n\nfunction refreshLockIcons() {\n  rows.forEach(r => {\n    const btn = g('lock-' + r);\n    if (!btn) return;\n    btn.innerHTML = lockedRow === r ? SVG_LOCKED : SVG_UNLOCKED;\n  });\n  refreshGreyState();\n}\n\nfunction refreshGreyState() {\n  \/\/ Reset all\n  rows.forEach(r => {\n    ['usable', 'raw', 'pct'].forEach(col => {\n      g(r + '-' + col).classList.remove('input-locked');\n    });\n    const btn = g('lock-' + r);\n    if (btn) btn.closest('tr').classList.remove('row-locked');\n  });\n\n  if (lockedRow) {\n    \/\/ Grey the entire locked row\n    ['usable', 'raw', 'pct'].forEach(col => {\n      g(lockedRow + '-' + col).classList.add('input-locked');\n    });\n    g('lock-' + lockedRow).closest('tr').classList.add('row-locked');\n  } else if (pctLocked) {\n    \/\/ Grey only the % column\n    rows.forEach(r => g(r + '-pct').classList.add('input-locked'));\n  }\n}\n\nfunction togglePctLock() {\n  pctLocked = g('pct-lock').checked;\n  if (pctLocked) {\n    lockedRow = null;\n    refreshLockIcons();\n  }\n  refreshGreyState();\n}\n\nfunction toggleRowLock(row) {\n  lockedRow = lockedRow === row ? null : row;\n  if (lockedRow) {\n    pctLocked = false;\n    g('pct-lock').checked = false;\n  }\n  refreshLockIcons();\n}\n\n\/\/ --- Input handlers ---\n\nfunction onUsable(row) {\n  const u = v(row + '-usable');\n  set(row + '-raw', u * 3);\n  if (pctLocked) {\n    const pct = v(row + '-pct');\n    if (pct <= 0) return;\n    const total = u \/ (pct \/ 100);\n    set('total-usable', total);\n    set('total-raw',    total * 3);\n    rows.forEach(r => {\n      if (r === row) return;\n      const ru = total * v(r + '-pct') \/ 100;\n      set(r + '-usable', ru);\n      set(r + '-raw',    ru * 3);\n    });\n    return;\n  }\n  recalcTotalFromRows();\n}\n\nfunction onRaw(row) {\n  const u = v(row + '-raw') \/ 3;\n  set(row + '-usable', u);\n  if (pctLocked) {\n    const pct = v(row + '-pct');\n    if (pct <= 0) return;\n    const total = u \/ (pct \/ 100);\n    set('total-usable', total);\n    set('total-raw',    total * 3);\n    rows.forEach(r => {\n      if (r === row) return;\n      const ru = total * v(r + '-pct') \/ 100;\n      set(r + '-usable', ru);\n      set(r + '-raw',    ru * 3);\n    });\n    return;\n  }\n  recalcTotalFromRows();\n}\n\nfunction onPct(row) {\n  \/\/ Ignore input on a locked row\n  if (lockedRow === row) return;\n\n  const total = v('total-usable');\n  if (total <= 0) return;\n\n  const newPct = v(row + '-pct');\n\n  \/\/ Update the edited row\n  set(row + '-usable', total * newPct \/ 100);\n  set(row + '-raw',    total * newPct \/ 100 * 3);\n\n  \/\/ Rows that absorb the change\n  const flexRows = rows.filter(r => r !== row && r !== lockedRow);\n  const lockedPct = lockedRow ? v(lockedRow + '-pct') : 0;\n  const remaining = Math.max(0, 100 - newPct - lockedPct);\n  const flexTotal = flexRows.reduce((s, r) => s + v(r + '-pct'), 0);\n\n  flexRows.forEach(r => {\n    const ratio = flexTotal > 0 ? v(r + '-pct') \/ flexTotal : 1 \/ flexRows.length;\n    const pct   = remaining * ratio;\n    set(r + '-pct',    pct);\n    set(r + '-usable', total * pct \/ 100);\n    set(r + '-raw',    total * pct \/ 100 * 3);\n  });\n\n  refreshTotal();\n}\n\nfunction onTotalUsable() {\n  const total = v('total-usable');\n  set('total-raw', total * 3);\n  if (pctLocked) {\n    rows.forEach(r => {\n      const u = total * v(r + '-pct') \/ 100;\n      set(r + '-usable', u);\n      set(r + '-raw',    u * 3);\n    });\n    return;\n  }\n  if (!lockedRow) return;\n  const lockedValue = v(lockedRow + '-usable');\n  const remaining   = Math.max(0, total - lockedValue);\n  const others      = rows.filter(r => r !== lockedRow);\n  const othersTotal = others.reduce((s, r) => s + v(r + '-usable'), 0);\n  others.forEach(r => {\n    const ratio = othersTotal > 0 ? v(r + '-usable') \/ othersTotal : 1 \/ others.length;\n    const u = remaining * ratio;\n    set(r + '-usable', u);\n    set(r + '-raw',    u * 3);\n  });\n  refreshPcts();\n}\n\nfunction onTotalRaw() {\n  const total = v('total-raw') \/ 3;\n  set('total-usable', total);\n  onTotalUsable();\n}\n\nfunction init() {\n  const total = 16;\n  set('total-usable', total);\n  set('total-raw',    total * 3);\n  setRow('data',   total * 0.8);\n  setRow('reco',   total * 0.2);\n  setRow('sparse', 0);\n  refreshPcts();\n  refreshLockIcons();\n  refreshGreyState();\n}\n\ndocument.addEventListener('DOMContentLoaded', init);\n\n<\/script>\n\n<div style=\"padding: 1rem 0;\">\n\n  <p style=\"font-size: 13px; color: var(--color-text-secondary); margin: 0 0 1rem 10px;\">\n    Edit any cell \u2014 usable, raw (\u00d73), % of total, or the total row itself. Other values update accordingly.\n  <\/p>\n\n  <div style=\"margin: 0 0 10px 10px;\">\n    <label>\n      <input type=\"checkbox\" id=\"pct-lock\" checked onchange=\"togglePctLock()\">\n      Lock percentages\n    <\/label>\n  <\/div>\n\n  <div style=\"overflow-x: auto;\">\n    <table class=\"asm-table\">\n\n      <thead>\n        <tr>\n          <th style=\"width: 60px;\">Lock<\/th>\n          <th style=\"width: 120px;\">Disk group<\/th>\n          <th>Usable space<\/th>\n          <th>Raw space (\u00d73)<\/th>\n          <th>% of total<\/th>\n        <\/tr>\n      <\/thead>\n\n      <tbody>\n        <tr>\n          <td>\n            <button type=\"button\" id=\"lock-data\" class=\"lock-btn\" onclick=\"toggleRowLock('data')\">&#x1F513;<\/button>\n          <\/td>\n          <td>\n            <div class=\"row-label\">\n              <span class=\"dot dot-data\"><\/span>DATA\n            <\/div>\n          <\/td>\n          <td>\n            <input type=\"number\" id=\"data-usable\" min=\"0\" step=\"1\" oninput=\"onUsable('data')\">\n            <span class=\"unit\">TB<\/span>\n          <\/td>\n          <td>\n            <input type=\"number\" id=\"data-raw\" min=\"0\" step=\"1\" oninput=\"onRaw('data')\">\n            <span class=\"unit\">TB<\/span>\n          <\/td>\n          <td>\n            <input type=\"number\" id=\"data-pct\" min=\"0\" max=\"100\" step=\"1\" oninput=\"onPct('data')\">\n            <span class=\"unit\">%<\/span>\n          <\/td>\n        <\/tr>\n\n        <tr>\n          <td>\n            <button type=\"button\" id=\"lock-reco\" class=\"lock-btn\" onclick=\"toggleRowLock('reco')\">&#x1F513;<\/button>\n          <\/td>\n          <td>\n            <div class=\"row-label\">\n              <span class=\"dot dot-reco\"><\/span>RECO\n            <\/div>\n          <\/td>\n          <td>\n            <input type=\"number\" id=\"reco-usable\" min=\"0\" step=\"1\" oninput=\"onUsable('reco')\">\n            <span class=\"unit\">TB<\/span>\n          <\/td>\n          <td>\n            <input type=\"number\" id=\"reco-raw\" min=\"0\" step=\"1\" oninput=\"onRaw('reco')\">\n            <span class=\"unit\">TB<\/span>\n          <\/td>\n          <td>\n            <input type=\"number\" id=\"reco-pct\" min=\"0\" max=\"100\" step=\"1\" oninput=\"onPct('reco')\">\n            <span class=\"unit\">%<\/span>\n          <\/td>\n        <\/tr>\n\n        <tr>\n          <td>\n            <button type=\"button\" id=\"lock-sparse\" class=\"lock-btn\" onclick=\"toggleRowLock('sparse')\">&#x1F513;<\/button>\n          <\/td>\n          <td>\n            <div class=\"row-label\">\n              <span class=\"dot dot-sparse\"><\/span>SPARSE\n            <\/div>\n          <\/td>\n          <td>\n            <input type=\"number\" id=\"sparse-usable\" min=\"0\" step=\"1\" oninput=\"onUsable('sparse')\">\n            <span class=\"unit\">TB<\/span>\n          <\/td>\n          <td>\n            <input type=\"number\" id=\"sparse-raw\" min=\"0\" step=\"1\" oninput=\"onRaw('sparse')\">\n            <span class=\"unit\">TB<\/span>\n          <\/td>\n          <td>\n            <input type=\"number\" id=\"sparse-pct\" min=\"0\" max=\"100\" step=\"1\" oninput=\"onPct('sparse')\">\n            <span class=\"unit\">%<\/span>\n          <\/td>\n        <\/tr>\n\n        <tr class=\"total-row\">\n          <td><\/td>\n          <td>\n            <div class=\"row-label\">\n              <span class=\"dot dot-total\"><\/span>Total\n            <\/div>\n          <\/td>\n          <td>\n            <input type=\"number\" id=\"total-usable\" min=\"0\" step=\"1\" oninput=\"onTotalUsable()\">\n            <span class=\"unit\">TB<\/span>\n          <\/td>\n          <td>\n            <input type=\"number\" id=\"total-raw\" min=\"0\" step=\"1\" oninput=\"onTotalRaw()\">\n            <span class=\"unit\">TB<\/span>\n          <\/td>\n          <td>\n            <span style=\"font-size: 14px; color: var(--color-text-secondary); padding: 4px 8px; display: inline-block;\">\n              100%\n            <\/span>\n          <\/td>\n        <\/tr>\n      <\/tbody>\n\n    <\/table>\n  <\/div>\n\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">When looking inside asmcmd, you see the &#8220;Raw space&#8221;. This is how much from disk space is used. The Usable space is what the users see and what you need to consider. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>In ExaCC and probably on Exadata in OCI it is sometimes a bit complex to calculate how much space you need to add to the ASM, as you can only change the total space and the distribution. When you just want to add 10TB (or GB) space to DATA diskgroup, you need to play a [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[51,67,82,21,52,6],"tags":[54],"class_list":["post-1134","post","type-post","status-publish","format-standard","category-cloud","category-engineer-systems","category-exacc","category-ideas","category-oci","category-oracle","tag-oci","czr-hentry"],"_links":{"self":[{"href":"https:\/\/anjo.pt\/keyword-oracle\/wp-json\/wp\/v2\/posts\/1134","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/anjo.pt\/keyword-oracle\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/anjo.pt\/keyword-oracle\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/anjo.pt\/keyword-oracle\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/anjo.pt\/keyword-oracle\/wp-json\/wp\/v2\/comments?post=1134"}],"version-history":[{"count":22,"href":"https:\/\/anjo.pt\/keyword-oracle\/wp-json\/wp\/v2\/posts\/1134\/revisions"}],"predecessor-version":[{"id":1163,"href":"https:\/\/anjo.pt\/keyword-oracle\/wp-json\/wp\/v2\/posts\/1134\/revisions\/1163"}],"wp:attachment":[{"href":"https:\/\/anjo.pt\/keyword-oracle\/wp-json\/wp\/v2\/media?parent=1134"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/anjo.pt\/keyword-oracle\/wp-json\/wp\/v2\/categories?post=1134"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/anjo.pt\/keyword-oracle\/wp-json\/wp\/v2\/tags?post=1134"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}