what storage is used in a LOBSEGMENT and should it be shrunk / reorg-1453350.1

2023-12-14 06:59

本文主要是介绍what storage is used in a LOBSEGMENT and should it be shrunk / reorg-1453350.1,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

How to Determine what storage is used in a LOBSEGMENT and should it be shrunk / reorganized? (文档 ID 1453350.1)

 

In this Document

Goal
Solution
References


This document is being delivered to you via Oracle Support's Rapid Visibility (RaV) process and therefore has not been subject to an independent technical review.

Applies to:

Oracle Database - Enterprise Edition - Version 9.2.0.8 and later
Information in this document applies to any platform.

Goal

Determine and demonstrate space usage within a LOBSEGMENT (CLOB / BLOB) and once determined decide if a shrink / reorganization is needed.
 

Solution

Older notes discussed the High Watermark within a LOBSEGMENT ... In reality ... this is only partially related to the issue of what is stored in the segment

There are currently (as of Oracle 11.2.0.3) two types of LOBSEGMENTS with regard to storage ... BASCIFILEs and SECUREFILEs

This note will address both types of storage

 

BASICFILES

Storage determination within a BASICFILE LOB cannot be determined with complete accuracy ... the following method may be used to determine the best information possible

DBMS_SPACE.SPACE_USAGE may not be used on basicfile lobs ... it is a new feature beginning in 11g and is only available for use on securefile lobs

1) Determine the segment name of the column to be examined

SELECT SEGMENT_NAME FROM DBA_LOBS WHERE WNER = '' AND TABLE_NAME = '

storage size of the LOBSEGMENT

SELECT SUM(BYTES) "STORAGE" FROM DBA_EXTENTS WHERE SEGMENT_NAME = '';

3) Determine the size of the LOB DATA

* BLOBs use the following query

     select sum(dbms_lob.getlength()) from ;

* CLOBs use the following note

     How to Return CLOB Size in Bytes like LENGTHB Function of CHAR/VARCHAR2 ( Document  790886.1)

4) Determine the size of the data that is not LOB DATA

     Subtract the result of #3 (the size of the LOB DATA) from #2 (the size of the LOB SEGMENT) ... this tells us the Undo Data size (expired + unexpired OR pctversion) + Unused space

5) Determine if the LOBSEGMENT is a candidate for shrink / reorganization

Information gathered

* The storage size of the LOBSEGMENT (how much space the LOB is occupying in the tablesapce) ... #1
* The size of the LOB DATA ... #2
* The size of the storage that is not LOB DATA #3

It is often assumed that if #3 is larger than #2 that space is being wasted ...
   This may or may not be true as it is not possible to tell the breakdown of space that is not LOB DATA

The following query will show the extents allocated for the LOBSEGMENT

SELECT BYTES, COUNT(*) FROM DBA_EXTENTS WHERE SEGMENT_NAME = ''  GROUP BY BYTES ORDER BY 2;

If the results of #3 are found to be one or more of the extent sizes from this query ...
    then this segment is a candiate for a shrink / reorganization as this process will likely be able to reduce the size of the LOBSEGMENT by at least one extent

WARNING : shrinking / reorganizing BASICFILE lobs can cause performance problems due to "enq: HW contention" waits

6) If #5 is true ... then one of the methods in the following note may be used to shrink / reorganize the lob segment

    How to Shrink (make less sparse) a LOB (BASICFILE or SECUREFILE)? (Document 1451124.1)

For an example of this process .. see  Case Study #1


SECUREFILES

Storage determination became much easier with the introduction of SECUREFILES

1) Determine the segment name of the column to be examined

SELECT SEGMENT_NAME FROM DBA_LOBS WHERE WNER = '' AND TABLE_NAME = '

     See Case Study #2 for syntax

Sample output:

Segment Blocks/Bytes   = 14360 / 117637120
Unused Blocks/Bytes    = 114 / 933888
Used Blocks/Bytes      = 12800 / 104857600
Expired Blocks/Bytes   = 1446 / 11845632
Unexpired Blocks/Bytes = 0 / 0
===========================================================================
NON Data Blocks/Bytes  = 1560 / 12779520

3) Determine if the LOBSEGMENT is a candidate for shrink / reorganization

The following query will show the extents allocated for the LOBSEGMENT

SELECT BYTES, COUNT(*) FROM DBA_EXTENTS WHERE SEGMENT_NAME = ''  GROUP BY BYTES ORDER BY 2;

If NON Data Bytes is one or more of the extent sizes from this query ...
     then this segment is a candiate for a shrink / reorganization as this process will likely be able to reduce the size of the LOBSEGMENT by at least one extent

4) If #3 is true ... then the method in the following note may be used to shrink / reorganize the lob segment

     How to Shrink a SECUREFILE LOB using Online Redefinition (DBMS_REDEFINITION)? (Document  1394613.1)


NOTE: The securefile lob space allocation algorithm is designed such that extra space is allocated to prevent enq: HW Contention waits ... as such ... it may be found that after shrinking / reorganizing a LOB ... the
           extra space shrunk may be quickly reallocated in order to prevent waits ... this is normal behavior.


For an example of this process .. see  Case Study #2

 



CASE STUDY #1: BASICFILE

create user test identified by test;
grant dba to test;
alter user test default tablespace users;
connect test/test;

-- CREATE THE TEST TABLES

CREATE TABLE test ( ID NUMBER, PHOTO BLOB ) ;
CREATE TABLE test_bfile ( B_FILE BFILE) ;

ALTER TABLE TEST MODIFY LOB (PHOTO) (RETENTION);

-- CREATE THE DIRECTORY IN WHICH THE BLOB (PHOTO) RESIDES

CREATE or REPLACE DIRECTORY test as '/home/oracle/kbcook';

-- INSERT THE BFILE LOCATOR FOR THE PHOTO

insert into test_bfile values ( bfilename('TEST','1.jpg'));

commit;

-- INSERT 100 COPIES OF THE PHOTO INTO THE TEST TABLE

declare
    tmp_blob blob default EMPTY_BLOB();
    tmp_bfile bfile:=null;
    dest_offset integer:=1;
    src_offset integer:=1;
begin
     select b_file into tmp_bfile from test_bfile;
     DBMS_LOB.OPEN (tmp_bfile, DBMS_LOB.FILE_READONLY);
     dbms_lob.createtemporary(tmp_blob, TRUE);
     DBMS_LOB.LOADBLOBFROMFILE(tmp_blob,tmp_bfile,DBMS_LOB.LOBMAXSIZE,dest_offset,src_offset);
     for i in 1..100 loop
          insert into test values(i,tmp_blob);
          commit;
     end loop;
     DBMS_LOB.CLOSE(tmp_bfile);
end;
/

-- EXAMINE THE SIZE OF THE LOB DATA (BEFORE GENERATING UNDO)

SELECT SUM(DBMS_LOB.GETLENGTH(PHOTO)) "LOB DATA" FROM TEST;

  LOB DATA
----------
 102382400

-- GENERATE UNDO COPIES FOR 33 ROWS

DELETE FROM TEST WHERE (ID/3) = TRUNC(ID/3);

COMMIT;

-- #1 DETERMINE THE SEGMENT NAME OF THE COLUMN TO BE EXAMINED

SELECT SEGMENT_NAME FROM DBA_LOBS WHERE WNER = 'TEST' AND TABLE_NAME = 'TEST' AND COLUMN_NAME = 'PHOTO';

SEGMENT_NAME
------------------------------
SYS_LOB0000067591C00002$$



-- #2 DETERMINE THE STORAGE SIZE OF THE LOBSEGMENT

SELECT SUM(BYTES) "STORAGE" FROM DBA_EXTENTS WHERE SEGMENT_NAME = 'SYS_LOB0000067591C00002$$';

STORAGE
----------
 109051904


-- #3 DETERMINE THE SIZE OF THE LOB DATA

SELECT SUM(DBMS_LOB.GETLENGTH(PHOTO)) "LOB DATA" FROM TEST;

LOB DATA
----------
  68596208

-- #4 DETERMINE THE SIZE OF THE DATA THAT IS NOT LOB DATA

SELECT 109051904-68596208 "non LOB DATA SIZE" FROM DUAL;

non LOB DATA SIZE
-----------------
         40455696

SELECT BYTES, COUNT(*) FROM DBA_EXTENTS WHERE SEGMENT_NAME = 'SYS_LOB0000067591C00002$$'  GROUP BY BYTES ORDER BY 2;

BYTES   COUNT(*)
---------- ----------
   8388608          5
     65536         16
   1048576         63

-- 5) DETERMINE IF THE LOBSEGMENT IS A CANDIDATE FOR SHRINK / REORGANIZATIONn

-- There are 40,455,696 bytes of storage that are being used by LOB data ... there are many extents small than this size ... this LOBSEGMENT is a candidate for shrink / reorganization

-- 6) If #5 is true ... then one of the methods in the following note may be used to shrink / reorganize the lob segment
--     How to Shrink (make less sparse) a LOB (BASICFILE or SECUREFILE)? (Document 1451124.1)

ALTER TABLE TEST ENABLE ROW MOVEMENT;

ALTER TABLE TEST SHRINK SPACE CASCADE;

SELECT SUM(BYTES) FROM DBA_EXTENTS WHERE SEGMENT_NAME = 'SYS_LOB0000067591C00002$$';

SUM(BYTES)
----------
  75694080


CASE STUDY #2: SECUREFILES

create user test identified by test;
grant dba to test;
alter user test default tablespace users;
connect test/test;

-- CREATE THE TEST TABLES

CREATE TABLE test ( ID NUMBER, PHOTO BLOB) LOB (PHOTO) STORE AS SECUREFILE ;
CREATE TABLE test_bfile ( B_FILE BFILE) ;

ALTER TABLE TEST MODIFY LOB (PHOTO) (RETENTION);

-- CREATE THE DIRECTORY IN WHICH THE BLOB (PHOTO) RESIDES

CREATE or REPLACE DIRECTORY test as '/home/oracle/kbcook';

-- INSERT THE BFILE LOCATOR FOR THE PHOTO

insert into test_bfile values ( bfilename('TEST','1.jpg'));

commit;

-- INSERT 100 COPIES OF THE PHOTO INTO THE TEST TABLE

declare
    tmp_blob blob default EMPTY_BLOB();
    tmp_bfile bfile:=null;
    dest_offset integer:=1;
    src_offset integer:=1;
begin
     select b_file into tmp_bfile from test_bfile;
     DBMS_LOB.OPEN (tmp_bfile, DBMS_LOB.FILE_READONLY);
     dbms_lob.createtemporary(tmp_blob, TRUE);
     DBMS_LOB.LOADBLOBFROMFILE(tmp_blob,tmp_bfile,DBMS_LOB.LOBMAXSIZE,dest_offset,src_offset);
     for i in 1..100 loop
          insert into test values(i,tmp_blob);
          commit;
     end loop;
     DBMS_LOB.CLOSE(tmp_bfile);
end;
/

-- CREATE A PROCEDURE TO EXAMINE THE SPACE USAGE OF THE SECUREFILE LOB SEGMENT

SET SERVEROUTPUT ON

CREATE OR REPLACE PROCEDURE check_space_securefile (u_name in varchar2, v_segname varchar2 ) IS
     l_segment_size_blocks NUMBER;
     l_segment_size_bytes NUMBER;
     l_used_blocks NUMBER;
     l_used_bytes NUMBER;
     l_expired_blocks NUMBER;
     l_expired_bytes NUMBER;
     l_unexpired_blocks NUMBER;
     l_unexpired_bytes NUMBER;
     l_unused_blocks NUMBER;
     l_unused_bytes NUMBER;
     l_non_data_blocks NUMBER;
     l_non_data_bytes NUMBER;

     BEGIN
          DBMS_SPACE.SPACE_USAGE( segment_owner =>u_name,
                                  segment_name => v_segname,
                                  segment_type => 'LOB',
                                  segment_size_blocks => l_segment_size_blocks,
                                  segment_size_bytes => l_segment_size_bytes,
                                  used_blocks => l_used_blocks,
                                  used_bytes => l_used_bytes,
                                  expired_blocks => l_expired_blocks,
                                  expired_bytes => l_expired_bytes,
                                  unexpired_blocks => l_unexpired_blocks,
                                  unexpired_bytes => l_unexpired_bytes
           );

          l_unused_blocks := l_segment_size_blocks - (l_used_blocks + l_expired_blocks + l_unexpired_blocks);
          l_unused_bytes := l_segment_size_bytes - (l_used_bytes + l_expired_bytes + l_unexpired_bytes);

          l_non_data_blocks := l_unused_blocks + l_expired_blocks + l_unexpired_blocks;
          l_non_data_bytes :=  l_unused_bytes + l_expired_bytes + l_unexpired_bytes;

          DBMS_OUTPUT.ENABLE;
          DBMS_OUTPUT.PUT_LINE(' Segment Blocks/Bytes   = '||l_segment_size_blocks||' / '||l_segment_size_bytes);
          DBMS_OUTPUT.PUT_LINE(' Unused Blocks/Bytes    = '||l_unused_blocks||' / '||l_unused_bytes);
          DBMS_OUTPUT.PUT_LINE(' Used Blocks/Bytes      = '||l_used_blocks||' / '||l_used_bytes);
          DBMS_OUTPUT.PUT_LINE(' Expired Blocks/Bytes   = '||l_expired_blocks||' / '||l_expired_bytes);
          DBMS_OUTPUT.PUT_LINE(' Unexpired Blocks/Bytes = '||l_unexpired_blocks||' / '||l_unexpired_bytes);
          DBMS_OUTPUT.PUT_LINE('===========================================================================');
          DBMS_OUTPUT.PUT_LINE(' NON Data Blocks/Bytes  = '||l_non_data_blocks||' / '||l_non_data_bytes);
     END;
/

-- #1 DETERMINE THE SEGMENT NAME OF THE COLUMN TO BE EXAMINED

SELECT SEGMENT_NAME FROM DBA_LOBS WHERE WNER = 'TEST' AND TABLE_NAME = 'TEST' AND COLUMN_NAME = 'PHOTO';

SEGMENT_NAME
------------------------------
SYS_LOB0000067626C00002$$


-- EXAMINE THE STORAGE USAGE IN THE LOBSEGMENT USING DBMS_SPACE_USAGE (BEFORE GENERATING UNDO)

exec check_space_securefile('TEST','SYS_LOB0000067626C00002$$');

Segment Blocks/Bytes   = 15000 / 122880000
Unused Blocks/Bytes    = 119 / 974848
Used Blocks/Bytes      = 12800 / 104857600
Expired Blocks/Bytes   = 2081 / 17047552
Unexpired Blocks/Bytes = 0 / 0
===========================================================================
NON Data Blocks/Bytes  = 2200 / 18022400


-- GENERATE UNDO COPIES FOR 33 ROWS

DELETE FROM TEST WHERE (ID/3) = TRUNC(ID/3);

COMMIT;

-- #2 DETERMINE THE STORAGE USAGE IN THE LOBSEGMENT USING DBMS_SPACE_USAGE

exec check_space_securefile('TEST','SYS_LOB0000067626C00002$$');

Segment Blocks/Bytes   = 15000 / 122880000
Unused Blocks/Bytes    = 119 / 974848
Used Blocks/Bytes      = 8576 / 70254592
Expired Blocks/Bytes   = 2081 / 17047552
Unexpired Blocks/Bytes = 4224 / 34603008
===========================================================================
NON Data Blocks/Bytes  = 6424 / 52625408



-- #3 DETERMINE IF THE LOBSEGMENT IS A CANDIDATE FOR SHRINK / REORGANIZATION

SELECT BYTES, COUNT(*) FROM DBA_EXTENTS WHERE SEGMENT_NAME = 'SYS_LOB0000067626C00002$$'  GROUP BY BYTES ORDER BY 2;

BYTES   COUNT(*)
---------- ----------
    131072          1
     65536          1
   8388608          6
   1048576         69


-- There are 52,625,408 bytes bytes of storage that are being used by LOB data ... there are many extents smaller than this size ... this LOBSEGMENT is a candidate for shrink / reorganization

-- 4) If #3 is true ... then the method in the following note may be used to shrink / reorganize the lob segment

--      How to Shrink a SECUREFILE LOB using Online Redefinition (DBMS_REDEFINITION)? (Document  1394613.1)

-- DETERMINE IF THE TABLE CAN BE REDEFINED ONLINE

BEGIN
    DBMS_REDEFINITION.CAN_REDEF_TABLE('TEST','TEST', DBMS_REDEFINITION.CONS_USE_ROWID);
END;
/

PL/SQL procedure successfully completed.

-- CREATE THE INTERIM TABLE

CREATE TABLE interim ( ID NUMBER, PHOTO BLOB) LOB (PHOTO) STORE AS SECUREFILE ;
ALTER TABLE interim MODIFY LOB (PHOTO) (RETENTION);

-- START THE REDEFINITION

BEGIN
   DBMS_REDEFINITION.START_REDEF_TABLE(
                uname => 'TEST',
                orig_table => 'TEST',
                int_table => 'INTERIM',
                options_flag => DBMS_REDEFINITION.CONS_USE_ROWID);
END;
/

-- FINISH THE REDEFINITION

exec DBMS_REDEFINITION.FINISH_REDEF_TABLE('TEST','TEST','INTERIM');

-- DROP THE INTERIM TABLE

DROP TABLE INTERIM;

--  THE REDEFINITION HAS CREATED A NEW TABLE AS SUCH THE SEGMENT NAME OF THE COLUMN OF THE NEW TABLE TO BE EXAMINED NEEDS TO BE DETERMINED

SELECT SEGMENT_NAME FROM DBA_LOBS WHERE WNER = 'TEST' AND TABLE_NAME = 'TEST' AND COLUMN_NAME = 'PHOTO';

SEGMENT_NAME
------------------------------
SYS_LOB0000067633C00002$$

exec check_space_securefile('TEST','SYS_LOB0000067633C00002$$');

Segment Blocks/Bytes   = 10128 / 82968576
Unused Blocks/Bytes    = 105 / 860160
Used Blocks/Bytes      = 8576 / 70254592
Expired Blocks/Bytes   = 1447 / 11853824
Unexpired Blocks/Bytes = 0 / 0
===========================================================================
NON Data Blocks/Bytes  = 1552 / 12713984


References

NOTE:1451124.1 - How to Shrink (make less sparse) a LOB (BASICFILE or SECUREFILE)?
NOTE:820043.1 - Why is no space released after an ALTER TABLE ... SHRINK?
NOTE:1394613.1 - How to Shrink a SECUREFILE LOB Using Online Redefinition (DBMS_REDEFINITION)?
 

相关内容

 
 

产品

 
  • Oracle Database Products > Oracle Database > Oracle Database > Oracle Database - Enterprise Edition > RDBMS > LOBs CLOBS BLOBs

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/17252115/viewspace-773465/,如需转载,请注明出处,否则将追究法律责任。

上一篇: LOB HWM CONTENTION,Using AWR to Identify Problem; Confirm,Verify Fix-837883.1
下一篇: Bug 6376915 - HW enqueue contention for ASSM LOB segments (文档 ID 6376915.8)
user_pic_default.png
请登录后发表评论 登录
全部评论
<%=items[i].createtime%>

<%=items[i].content%>

<%if(items[i].items.items.length) { %>
<%for(var j=0;j
<%=items[i].items.items[j].createtime%> 回复

<%=items[i].items.items[j].username%>   回复   <%=items[i].items.items[j].tousername%>: <%=items[i].items.items[j].content%>

<%}%> <%if(items[i].items.total > 5) { %>
还有<%=items[i].items.total-5%>条评论 ) data-count=1 data-flag=true>点击查看
<%}%>
<%}%> <%}%>
rongshiyuan

注册时间:2009-11-24

  • 博文量
    798
  • 访问量
    3202704

最新文章

  • ASM Di Show PROVISIONED On One RAC,UNKNOWN Other Node,Cannot Add To DG_1468642.1
  • Execution of DBMS_METADAT.GET_DDL results in ORA-19206,ORA-6512_292266.1
  • Calling Dbms_metadata.Get_ddl From Stored Procedure Results Ora-31603_463483.1
  • Linux: How To Setup UDEV Rules For RAC OCR Voting Dev On SLES10,RHEL5_414897.1
  • Config DS devices for use Oracle ASM 11.2/12.1 IBM:Linux on System z_1377392.1
  • Setting up ASM on linux with LVM (Doc ID 292348.1)
  • Configuring device-mapper for CRS/ASM (Doc ID 357472.1)
  • Manage ASM instance-creating diskgroup,adding/dropping/resizing disks_270066.1
  • Oracle Linux and External Storage Systems (Doc ID 753050.1)
  • Config and Use of Device Mapper Multipathing on Oracle Linux (OL)_555603.1

转载于:http://blog.itpub.net/17252115/viewspace-773465/

这篇关于what storage is used in a LOBSEGMENT and should it be shrunk / reorg-1453350.1的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/491572

相关文章

MongoDB学习—(1)安装时出现The default storage engine 'wiredTiger' is not available问题解决

MongoDB是NoSql类型的一种基于分布式文件存储的数据库,其存储方式与关系型数据库不同。其详细解释可见于[百科]。安装文件可从官网下载,官网:http://mongodb.org 我将下载的解压文件放到D盘的mongodb文件夹下,

浏览器百科:网页存储篇-Session storage应用实例(九)

1.引言 在前面的文章中,我们详细介绍了如何在 Chrome 浏览器中打开并使用 Session storage 窗格,进行数据的查看、编辑和管理。作为网页存储技术的重要组成部分,sessionStorage在提升用户体验和数据管理能力方面发挥了重要作用。在本篇《浏览器百科:网页存储篇-Session storage应用实例(九)》中,我们将深入探讨sessionStorage的实际应用场景,通

浏览器百科:网页存储篇-Session storage介绍(七)

1.引言 在上一篇文章中,我们详细探讨了 localStorage 的各种应用实例和使用方法。本篇文章将继续网页存储系列,聚焦于 Session storage。Session storage 与 localStorage 类似,都用于在客户端存储数据,但它们之间存在一些关键差异。通过了解 Session storage 的特性和应用场景,开发者可以更灵活地选择和运用网页存储技术,提升网页应用的

shell系列------查看storage下有没有某个文件目录

如果某个分区mount成功,那么storage下会长出两个目录文件来,那么用脚本怎么实现呢,如下代码即可 #!/system/bin/sh   //要注意不同的解释器需要不同的sh num=`ls /storage | wc -l`  //wc是为了获取文件里的行数 if [ $num -gt 2 ] then echo "1" else echo "0" fi

以太坊存储类型(memory,storage)及变量存储详解

1数据存储位置(Data location)概念 1.1 storage, memory, calldata, stack区分 在 Solidity 中,有两个地方可以存储变量 :存储(storage)以及内存(memory)。 Storage变量是指永久存储在区块链中的变量。 Memory 变量则是临时的,当外部函数对某合约调用完成时,内存型变量即被移除。 内存(memory)位置

从一到无穷大 #34 从Columnar Storage Formats评估到时序存储格式的设计权衡

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作),由 李兆龙 确认,转载请注明版权。 文章目录 引言Parquet / ORC功能与结构对比差异Indexes and Filters压缩影响 TsFile总结 引言 随着 Parquet,ORC,TsFile等开源存储格式的发展,各家时序厂商的压缩

StarRocks 巧用 Storage Volume,强大又便捷

前言 StarRocks 存算分离支持使用各种外部独立存储系统来存储业务数据。在早期 3.0 版本中,用户需要在 fe.conf 中配置存储相关信息(如 endpoint 等),这种静态配置模式也给用户使用带来了很多的不便性。 为此,StarRocks 存算分离从 3.1.0 版本后推出了 Storage Volume 能力,支持用户动态地为集群创建存储资源。需要说明的是,Storage Vo

【ORACLE】LOBSEGMENT类型对象清理

在Oracle数据库中,LOBSEGMENT类型的对象通常用于存储大型对象(LOB),如BLOB(二进制大对象)和CLOB(字符大对象)。如果需要清理LOBSEGMENT对象以释放空间,可以采取以下步骤: 确定LOBSEGMENT对象的来源:首先,你需要确定哪个表和哪个字段使用了这个LOBSEGMENT。可以通过查询dba_objects和dba_lobs视图来获取这些信息。例如,使用以下SQ

Storage:Keeping memories in the brain(存储:把记忆保存在大脑中)

Once you’ve encoded information, you now need to store it. Unfortunately, forgetting is a major part of how our brains work.Most of us can’t remember what we had for dinner Tuesday, three weeks ago.Ho