2019周笔记(2.25-3.01)(压缩数据库)

公司穷,硬盘少,传感数据多,时不时就需要压缩数据库,这周都在干这个事,就稍微专注的看了下[dbcc shrinkfile ]和[dbcc shrinkdatabase ]的区别,发现还是没看懂,而且有文章说做过多次试验后发现msdn中的说法也不是完全正确。

那这次就只记录一些比较关键的东西。首先[dbcc shrinkfile ]是[dbcc shrinkdatabase ]的一个执行子集,也就是执行[dbcc shrinkdatabase ]其实是对多个文件进行[dbcc shrinkfile ]操作。

基本语法:
dbcc shrinkfile(文件名|文件id,希望将日志收缩到的目标大小,emptyfile | notruncate | truncateonly)
–文件名(很多朋友这里容易填错,这里可以去数据库右键属性中,找到“文件”菜单中,里面的“逻辑名称”)
–目标大小,也就是我们希望把文件压缩到的理想尺寸,单位mb,如果一个日志有10g,我们希望压缩到1g,但是实际数据已经占用3g,那么最终压缩出来也是3g。
–notruncate | truncateonly参考下面shrinkdatabase,这里只说emptyfile。它是通过把数据迁移到文件组的中的其他文件来清空源文件,然后配合使用alter database [数据库名称] remove file [filea] 命令。(可是我自己测试执行后总是提示“文件组中空间不足,无法完成清空文件操作”,有理解的童鞋可以留言跟我说下,硬盘空间肯定是足够的。)

基本语法:
dbcc shrinkdatabase(数据库名|数据库id|0,目标百分比,notruncate|truncateonly)
–第一个参数0,表示收缩当前数据库
–目标百分比,可选,据说是只对notruncate起作用,因为truncateonly只是截断尾部(这个参数是最难理解的,看了好几篇文章,每个人的说法都不一样)(其中一篇博文通过测试,说明msdn写法有误,正确的是百分比只对truncateonly生效,对notruncate反而没有作用http://www.mamicode.com/info-detail-1493145.html)
–第三个参数可选,notruncate表示将文件末尾已分配的页移动到文件前面未分配的页。文件末尾的可用空间不会返回给操作系统,文件的物理大小也不会改变。truncateonly表示将文件末尾的所有可用空间都会释放给操作系统,但不在文件内部执行页移动操作。因此,使用此参数数据文件只能收缩最近分配的区。有文章称在不选择时,会先执行notruncate,然后执行truncateonly。

结果集列解释。
dbid 数据库引擎试图收缩的文件的数据库标识号。
fileid 数据库引擎试图收缩的文件的文件标识号。
currentsize 文件当前占用的 8 kb 页数。
minimumsize 文件最低可以占用的 8 kb 页数。 此数字对应于文件的大小下限或最初创建大小。
usedpages 文件当前使用的 8 kb 页数。
estimatedpages 数据库引擎估计文件能够收缩到的 8 kb 页数。

注:收缩操作不是一件值得经常执行的操作,会带来碎片, 下面带来重建索引的方法。
整理index的方式有两种:
dbcc indexdefrag(db, table, index) with no_infomsgs 和
dbcc dbreindex(table, ”, 0)
indexdefrag是在线重整index,不会对table锁定,但是由于indexdefrag是对index的重组,所以index的数据页不一定是连续的。

dbreindex会对table进行锁定,重建索引。

 

–2019.02.25

压缩数据库,释放物理空间
alter database iotdb_beta set recovery simple
dbcc shrinkdatabase(iotdb_beta,5)

//或者直接压缩日志文件

//dbcc shrinkfile (n’iotdb_beta_log’ , 5) 

alter database iotdb_beta set recovery full

 

–2019.02.26
查看数据库各个表占用的空间,以及个表的索引所占空间(这个暂时不深究了,反正挺好用,观察表数据占用空间以及索引占用的空间)
;with cte as (
(select t.name as tablename,i.name as indexname,
sum(row_count)as row_count,
sum (s.used_page_count) as used_pages_count

from sys.dm_db_partition_stats as s
join sys.tables as t on s.object_id = t.object_id
join sys.indexes as i on i.[object_id] = t.[object_id] and s.index_id = i.index_id
group by t.name, i.name)
union all
(select t.name as tablename,i.name as indexname,
sum(row_count)as row_count,
sum (s.used_page_count) as used_pages_count
from sys.dm_db_partition_stats as s
join sys.views as t on s.object_id = t.object_id
join sys.indexes as i on i.[object_id] = t.[object_id] and s.index_id = i.index_id
group by t.name, i.name)
)
select
cte.tablename,
cte.indexname,
cast((cte.used_pages_count * 8.)/1024 as decimal(10,3)) as tablesizeinmb
from cte
order by 1 desc;
go

 

–2019.02.27
一、在普通同步方法中调用异步方法。

public async task testasyncmethod()
{
//do it...
}

//在主方法中调用,加上wait();因为场景中这里不需要异步,如果不加wait()会导致testasyncmethod方法还没有得到结果前,程序已经往下运行。

testasyncmethod().wait();

同样的场景如果需要拿到异步方法的返回值

public async task<int> testasyncmethodwithreturn()
{
    //do it...
    return 0;
}

//主方法中

testasyncmethodwithreturn().wait();
int i = testasyncmethodwithreturn().getawaiter().getresult();

 

二、相反的,如果想在异步方法中去调用同步方法。出现这想法,是因为我本来有一系列webapi异步方法在执行,异步方法的最后一步去调用spring dao操作数据库,这个是不能异步的,所以只能在异步中去调用同步方法,最开始我的写法是这样:

public async task<int> asyncexecutesql(string sql)
{
    task<int> task = new task<int>(() =>     basedao.executenonquerysql(sql));
    task.start();
    int x = await task;
    //或者
    //int x = await task.run(() => basedao.executenonquerysql(sql)); 
    return x;
}

一直都执行的好好地,我以为没什么问题,直到有一天我写了一个大批量导入演示数据的功能,其中我用winform多次调用其中一个异步方法时,莫名其妙只执行一次,但是就是不返回信息,导致所有程序阻塞。后来查了好久,看到了微软文档中一个官方方法,用委托方法。(https://docs.microsoft.com/zh-cn/dotnet/standard/asynchronous-programming-patterns/calling-synchronous-methods-asynchronously)

/*第一步创建异步回调委托*/
/// <summary>
/// 在异步方法中调用同步数据库操作方法委托
/// </summary>
/// <param name="sql"></param>
/// <returns></returns>
public delegate int asyncexecutesqlcaller(string sql);

/*第二步用委托去调用需要被调用的方法*/
/// <summary>
/// 直接执行拼接好的sql(异步)
/// </summary>
/// <param name="sql"></param>
public async task<int> asyncexecutesql(string sql)
{

    asyncexecutesqlcaller caller = new asyncexecutesqlcaller(basedao.executenonquerysql);
    iasyncresult result = caller.begininvoke(sql, null, null);
    int x = caller.endinvoke(result);//这里会阻塞线程,所以这种方法不能用在视图层,否则会卡死界面。 
    return x;
}

修改完成后,最终测试在webapi、和winform中都能正常运行。但是我依旧不明白问题出在哪里,最近没有时间深究,后面再找高手指点迷津。

 

 –2019.02.28

一、mvc中如何给所有action加上校验特性,同时对个别action网开一面,例如

1、如何给控制器的每个方法都加上session校验特性,一般是进行登录判断。

 /*第一步、加上特性类*/
    public class authenticationattribute : actionfilterattribute
    {
        public authenticationattribute()
        {
            this.isusedattribute = true;//这个构造方法在这个场景下是多余的,但是如果写的特写比较复杂,需要一些特定初始化时,就比较有效。
        }

        /// <summary>
        /// 是否启用session验证
        /// </summary>
        public bool isusedattribute
        {
            get;
            set;
        }

        public override void onactionexecuting(actionexecutingcontext filtercontext)
        {
            if (filtercontext.httpcontext.session["userid"] == null || string.isnullorwhitespace(filtercontext.httpcontext.session["userid"].tostring()))
            {
                if (isusedattribute)
                {
                    filtercontext.result = new redirecttorouteresult("default", new system.web.routing.routevaluedictionary(new
                    {
                        action = "login",
                        controller = "user"
                    }));
                }
            }  
            base.onactionexecuting(filtercontext);
        }
    }

 

/*第二步,把特性加到过滤器,表示所有action 都受这个特性约束*/
    public class filterconfig
    {
        public static void registerglobalfilters(globalfiltercollection filters)
        {
            filters.add(new handleerrorattribute());
            filters.add(new authenticationattribute());
        }
    }

 

 

/*第三步,在不需要的action前单独设置*/

        [authenticationattribute(isusedattribute = false)]
        public actionresult login()
        {
            return view();        
        }dbcc shrinkfile (n'db_name_log' , 11, truncateonly) 

 

(0)
上一篇 2022年3月21日
下一篇 2022年3月21日

相关推荐